【问题标题】:Specifying the return value for xUnit Theory tests指定 xUnit Theory 测试的返回值
【发布时间】:2020-04-20 07:38:48
【问题描述】:

是否可以为理论案例指定返回值?就像我有测试方法一样:

[Theory]
[MemberData(nameof(TestCases))]
public async Task<bool> Test(int i, double d, string str)
{
    return DoStuffAsync(i, d, str);
}

方法

public static IEnumerable<object[]> TestCases()
{
    yield return new object[] { 1, Math.PI, "case1", true };
    yield return new object[] { 2, Math.E,  "case2", false };
}

生成测试用例。

但是如果我尝试运行这些测试用例,我会得到错误

System.InvalidOperationException : The test method expected 3 parameter values, but 4 parameter values were provided.

【问题讨论】:

  • 您只需添加第四个参数,例如bool expected value,并将输出与 Assert 中此参数的值进行比较。

标签: c# .net unit-testing xunit


【解决方案1】:

您可以稍微重写您的测试,通过添加预期结果的参数并将其在Assert 中与从DoStuffAsync 方法返回的值进行比较。另外不要忘记将测试方法的返回值从 Task&lt;bool&gt; 更改为 Taskasync void,因为您正在检查测试中的返回值并且什么都不返回

[Theory]
[MemberData(nameof(TestCases))]
public async Task Test(int i, double d, string str, bool expected)
{
    var result = await DoStuffAsync(i, d, str);
    Assert.Equal(expected, result);
}

【讨论】:

    【解决方案2】:

    您不能为理论测试用例指定返回值,但您可以添加一个类似于预期值的参数,并将测试输出与该值进行比较。在这种情况下,测试将如下所示:

    [Theory]
    [MemberData(nameof(TestCases))]
    public async Task Test(int i, double d, string str, bool expectedValue)
    {
         bool actualValue = DoStuffAsync(i, d, str);
         Assert.True(actualValue == expectedValue);
    }
    

    这将告诉框架预期值是否等于 DoStuffAsync 方法产生的实际值。 Assert 语句用于评估测试是通过还是失败。

    另一种可能很容易维护的方法是将一个测试分成两个。在第一个中,您可以期望每个案例的方法输出为真,而在第二个中,您可以期望每个案例的输出为假。

    第一个测试应该是这样的

    [MemberData(nameof(TestCasesTrue))]
    public async Task TestTrue(int i, double d, string str)
    {
         bool actualValue = DoStuffAsync(i, d, str);
         Assert.Equal(true, actualValue);
    }
    

    第二个测试是这样的:

    [MemberData(nameof(TestCasesFalse))]
    public async Task TestFalse(int i, double d, string str)
    {
         bool actualValue = DoStuffAsync(i, d, str);
         Assert.Equal(false, actualValue);
    }
    

    【讨论】:

    • 对于非异步方法,返回类型应该是void,对于异步方法,返回类型应该是TaskTask&lt;T&gt; 没有任何价值。
    • Assert.True 仅接受单个参数,Assert.Equal 应改为
    • 使用Assert.True(a == b)Assert.Equals(a, b) 可读性差得多,并且给出的断言消息更难解释。在第二种情况下,它会说它期望true 但得到false,即使测试用例正在测试该值为false。使用Equals 会给出更清晰的信息,例如“预期为假,但结果为真”。
    • @MartinCostello 这并不完全正确,因为Assert.True(a==b) 只是检查您写入其中的条件是否为真。 Assert.True(a==b) 的好处是您可以添加一条消息,当测试失败时会显示该消息,例如 Assert.True(a==b,"Test failed"),如果您有多个 Assert 语句,我们将非常有用。
    • 您可以添加一条消息,但根据我的经验,我仍然发现使用 Equals 并且 有一条消息会更好。另外,您在 Equals 场景中有一个数据驱动的测试,而不是两个几乎相同的测试,因此需要维护的东西更少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多