首页 > 解决方案 > 遍历使用 yield 的 IEnumerable

问题描述

我已经开始对我的系统进行单元测试,并且有一堆测试(使用 Xunit)采用以下 TestData(),一次一个向量:

public static IEnumerable<object[]> TestData()
{
   yield return new object[] { true, false };
   yield return new object[] { false, false };
   yield return new object[] { true, true };
   yield return new object[] { false, true };
}

现在我想知道是否有办法在同一个/单个测试中(重新)使用整个集合。
例如,这是我正在尝试设置的测试:

[Theory]
public void CanCheckAllInOneGo()
{
    bool error = false;

    // The foreach does not work
    foreach (var a in TestData())
    {
        error |= doSomething(a[0], a[1]);
    }
            
    Assert.True(error != true, "doSomething() failed");
} 

注意,为了一次运行一个向量,我之前使用了以下属性:

[Theory]
[MemberData(nameof(TestData))]

也许这是不可能的,因为“产量”。如果没有,你会怎么做?谢谢。

标签: c#foreachienumerablexunit

解决方案


如果你想要参数化测试,你应该像这样使用 InlineData 属性:

[Theory]
[InlineData(true, false)]
[InlineData(false, false)]
[InlineData(true, true)]
[InlineData(false, true)]
public void CanCheckAllInOneGo(bool value1, bool value2)
{      
    Assert.True(doSomething(value1, value2), "doSomething() failed");
}

https://andrewlock.net/creating-parameterised-tests-in-xunit-with-inlinedata-classdata-and-memberdata/

该文章还解释了如何使用 MemberData 属性来重用测试数据。

[Theory]
[MemberData(nameof(TestData))]
public void CanCheckAllInOneGo(bool value1, bool value2)
{      
    Assert.True(doSomething(value1, value2), "doSomething() failed");
}

public static IEnumerable<object[]> TestData()
{
   yield return new object[] { true, false };
   yield return new object[] { false, false };
   yield return new object[] { true, true };
   yield return new object[] { false, true };
}

如果您真的想在 [Fact] 测试中使用 TestData 生成器,那么您就在正确的轨道上,您只是忘记将对象转换回布尔值:

[Fact]
public void CanCheckAllInOneGo()
{
    varerror = false;

    foreach (var a in TestData())
    {
        error |= doSomething((bool)a[0], (bool)a[1]);
    }

    Assert.True(error != true, "doSomething() failed");
}


推荐阅读