使 ClassData 从 IEnumerable<object[]> 中选择前 n 个元素

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

给定 xUnit 测试项目中的以下模拟数据

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();
}

我想用那个 class 进行两次测试

[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);
}

但如您所见,第一个测试只接受一个参数。当 运行 测试第一个失败并出现此异常时

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

有没有办法让 ClassData 从该对象中选择第一列并忽略其余列?

有很多方法可以解决这个问题。我能想到的几个解决方案:


使用会员数据

[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();
}

给方法加一个参数,忽略:

[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);
}