在单元测试中使用 InlineData 的困难 - 参数是一个控制器
Difficulties using InlineData in Unit Test - parameter is a controller
我是测试新手,现在正在学习使用 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 示例不正确 - 但我试图通过说出更清晰的代码来指出我正在寻找的东西。通过遵循测试用例逻辑,我可以轻松地将我的测试扩展到 10-15 个不同的测试用例。我听说 xUnit 对 InlineData 做了类似的事情(LasseVågsætherKarlsen 告诉我这是不可能的) - 或者 MemberClass 或 ClassData。
可能性 1
- 创建
MyControllerClassData
public class MyControllerClassData : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] {
new MyController
{
Id = 1,
// ...
}
};
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
- 修改你的理论
[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
- 在构造函数中创建 MyController class 并将其存储在私有 属性
- 将参数更改为字符串和您想要的
objectResult
- 始终使用相同的 MyController,使用字符串执行
Get()
并根据预期的 objectResult
对其进行验证。
这个解决方案看起来更清晰一些,因为您对每种情况都有一个测试。
我终于把它修好了。实际上可以使用 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);
}
在我看来,这是一种非常简单的方法 - 与在网上搜索时找到的方法相比 - 希望它对其他人也有用。
我是测试新手,现在正在学习使用 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 示例不正确 - 但我试图通过说出更清晰的代码来指出我正在寻找的东西。通过遵循测试用例逻辑,我可以轻松地将我的测试扩展到 10-15 个不同的测试用例。我听说 xUnit 对 InlineData 做了类似的事情(LasseVågsætherKarlsen 告诉我这是不可能的) - 或者 MemberClass 或 ClassData。
可能性 1
- 创建
MyControllerClassData
public class MyControllerClassData : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] {
new MyController
{
Id = 1,
// ...
}
};
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
- 修改你的理论
[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
- 在构造函数中创建 MyController class 并将其存储在私有 属性
- 将参数更改为字符串和您想要的
objectResult
- 始终使用相同的 MyController,使用字符串执行
Get()
并根据预期的objectResult
对其进行验证。
这个解决方案看起来更清晰一些,因为您对每种情况都有一个测试。
我终于把它修好了。实际上可以使用 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);
}
在我看来,这是一种非常简单的方法 - 与在网上搜索时找到的方法相比 - 希望它对其他人也有用。