Skip to content

🐛 Xunit3 TheoryData does not work with MemberAutoData/ClassAutoData #1

@pinkfloydx33

Description

@pinkfloydx33

Describe the Bug

When working with MemberAutoData or ClassAutoData, Xunit3's TheoryData<> (or TheoryDataRow<>-based classes) no longer work. An exception will be thrown at test execution time indicating that the member or class must implement IEnumerable<object[]>:

Class Data:

System.InvalidOperationException
Data source type "MyProject.Tests.MyClassData" should implement the "System.Collections.Generic.IEnumerable`1[System.Object]" interface.

Member Data:

System.ArgumentException
Member MyMemberData on MyProject.Tests.MyTestClass does not return IEnumerable<object[]>

This works just fine with Xunit2 where TheoryData<> implicitly implements IEnumerable<object[]> via IReadOnlyCollection<object[]>. However TheoryData<> in Xunit3 has been completely revamped and works in terms of TheoryDataRow which is very different.

Scenario

// class data
public class MyClassData : TheoryData<string, string> 
{
    public MyClassData() 
    {
       Add("A", "B");
    }
}

public class TestClass 
{
  // member data
  public static TheoryData<string, string> MyMemberData => new() {
      { "A", "B" }
  };

  [Theory]
  [MemberAutoData(nameof(MyMemberData)]
  public void MyTest(string x, string y, int autodata) {   }

  [Theory]
  [ClassAutoData(typeof(MyClassData)]
  public void MyTest(string x, string y, int autodata) {   }
}

Expected Behavior

Both tests should run, sourcing data from the appropriate member or class and fill in the remaining parameters via AutoFixture

More Information

  • .NET 9
  • Libraries:
    • xunit.v3: 2.0.3
    • AutoFixture: 5.0.0-preview0012
    • AutoFixture.Xunit3: 5.0.0-preview0012

The ClassData scenario can at least be worked around by implementing IEnumerable<object[]> yourself:

public class MyClassData : TheoryData<string, string>, IEnumerable<object[]>
{
    public MyClassData() 
    {
       Add("A", "B");
    }
    IEnumerator<object[]> IEnumerable<object[]>.GetEnumerator()
    {
        foreach (var r in this)
            yield return [ r.Data.Item1, r.Data.Item2 ];
    }
}

Though this defeats the purpose of using TheoryData

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions