在单元测试中使用InlineData的困难-参数是控制器

时间:2019-10-04 09:58:42

标签: c# unit-testing xunit

我不熟悉测试,现在正在学习使用xUnit。

我编写了下面的测试,该测试可以工作并给出我想要的结果,但是我认为我应该能够使其变得更整洁,就像在nUnit中使用TestCase一样。因此,我尝试使用InlineData,我知道它是xUnits“ TestCase”,但我不知道该怎么做。

当尝试进行设置时,如下所示(请参见注释过的行),然后它告诉我

    [Theory]
    // [InlineData("")] // wanna use InlineData just to make the code/test cleaner.
    // [InlineData(null)]
    public async Task Get_Return_Something(
        MyController sut)
    {
        var result1 = await sut.Get(""); // when placing "sut" as param, I get: cannot convert from MyController to string. 
        var result2 = await sut.Get(null); // same applies here..

        result1.ShouldBeOfType(typeof(OkObjectResult));
        result2.ShouldBeOfType(typeof(BadRequestObjectResult));
    }

我的问题是-如何实现InlineData以便测试更干净。甚至当我将控制器作为参数时,是否有可能?

仅作说明->是否应该使用nUnit中的语法:

// something like this
[TestCase("", OkObjectResult)]
[TestCase(null, BadRequestObjectResult)]
public async Task Get_Return_Something(MyController sut, param1, param2)
{
    var result = await.sut.Get(param1);
    result.ShouldBeOfType(typeof(param2));
}

也许nUnit示例不正确-但我想通过说出更简洁的代码来指出我在寻找什么。通过遵循TestCase逻辑,我可以轻松地将测试扩展到10-15个不同的TestCases。而且我听说xUnit与InlineData相似(LasseVågsætherKarlsen告诉我不可能)-或然后是MemberClass或ClassData。

2 个答案:

答案 0 :(得分:0)

可能性1

  1. 创建一个MyControllerClassData
    public class MyControllerClassData : IEnumerable<object[]>
    {
        public IEnumerator<object[]> GetEnumerator()
        {
            yield return new object[] {
                new MyController
                {
                  Id = 1,
                  // ...
                }
            };
        }
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
  1. 修改理论
    [Theory]
    [ClassData(typeof(MyControllerClassData))]
    public async Task Get_Return_Something(MyController sut)
    {
        var result1 = await sut.Get(""); // when placing "sut" as param, I get: cannot convert from MyController to string. 
        var result2 = await sut.Get(null); // same applies here..

        result1.ShouldBeOfType(typeof(OkObjectResult));
        result2.ShouldBeOfType(typeof(BadRequestObjectResult));
    }

可能性2

  1. 在构造函数中创建MyController类,并将其存储在私有属性中
  2. 将参数更改为字符串和所需的objectResult
  3. 始终使用相同的MyController,使用字符串执行Get(),并根据预期的objectResult对其进行验证。

此解决方案似乎更干净一些,因为您针对每种情况进行了一次测试。

答案 1 :(得分:0)

最后,我设法将其修复。实际上可以使用InlineData-只是不如nUnit那样简单(imo)。解决方法如下:

[Theory]
[InlineData("", typeof(OkObjectResult))]
[InlineData(null, typeof(BadRequestObjectResult))]
public async Task Get_Return_Something(param1, param2){

    // moq MyController with its parameters/objects
    ...


    var result = await sut.Get(param1);

    result.ShouldBeOfType(param2);
}

在我看来,与在网上搜索时发现的方法相比,这是一种非常简单的方法,希望它对其他人也有用。