简体   繁体   中英

Make ClassData pick first n elements from IEnumerable<object[]>

Given the following mock data in a xUnit tests project

public sealed class MockData : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        yield return new object[] { "First", 1 };
        yield return new object[] { "Second", 2 };
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

I want to use that class for two tests

[Theory]
[ClassData(typeof(MockData))]
private void FirstTest(string foo)
{
    Assert.True(true);
}
    
[Theory]
[ClassData(typeof(MockData))]
private void SecondTest(string foo, int bar)
{
    Assert.True(true);
}

but as you can see the first test only takes in one parameter. When running the tests the first one fails with this exception

System.InvalidOperationException: The test method expected 1 parameter value, but 2 parameter values were provided.

Is there a way I can make the ClassData pick the first column from that object and ignore the rest?

There are many ways to solve this. A few solutions I can think of:


Use MemberData

[Theory]
[MemberData(nameof(MockData.ColumnA), MemberType= typeof(MockData))]
private void ColATest(string foo) => ...

[Theory]
[MemberData(nameof(MockData.ColumnB), MemberType= typeof(MockData))]
private void ColBTest(string foo) => ...

[Theory]
[ClassData(typeof(MockData))]
private void SecondTest(string foo, int bar)
{
   Assert.True(true);
}

public sealed class MockData : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        yield return new object[] { "First", 1 };
        yield return new object[] { "Second", 2 };
    }

    public IEnumerable<string> ColumnA => this.Select(x => x[0]);
    public IEnumerable<int> ColumnB => this.Select(x => x[1]);

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

Add a parameter to the method and ignore it:

[Theory]
[ClassData(typeof(MockData))]
private void FirstTest(string foo, int bar)
{
    // just don't use 'bar'
    Assert.True(true);
}
    
[Theory]
[ClassData(typeof(MockData))]
private void SecondTest(string foo, int bar)
{
    Assert.True(true);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM