带有泛型的 NUnit 测试用例
有没有办法使用 TestCase 将泛型类型传递给 NUnit 中的测试?
这是我想做的,但语法不正确......
[Test]
[TestCase<IMyInterface, MyConcreteClass>]
public void MyMethod_GenericCall_MakesGenericCall<TInterface, TConcreteClass>()
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<TInterface>();
// Assert
Assert.IsInstanceOf<TConcreteClass>(response);
}
或者如果不正确,最好的方法是什么实现相同的功能(显然我在实际代码中会有多个测试用例)?
使用另一个示例更新...
这是传递了单个泛型类型的另一个示例...
[Test]
[TestCase<MyClass>("Some response")]
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
Is there any way to pass generic types using a TestCase to a test in NUnit?
This is what I would like to do but the syntax is not correct...
[Test]
[TestCase<IMyInterface, MyConcreteClass>]
public void MyMethod_GenericCall_MakesGenericCall<TInterface, TConcreteClass>()
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<TInterface>();
// Assert
Assert.IsInstanceOf<TConcreteClass>(response);
}
Or if not, what is the best way to achieve the same functionality (obviously I'll have multiple TestCases in the real code)?
Update with another example...
Here is another example with a single generic type passed...
[Test]
[TestCase<MyClass>("Some response")]
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
NUnit 测试方法实际上可以是泛型的,只要可以从参数推断出泛型类型参数即可:
如果无法推断通用参数,测试运行程序将不知道如何解析类型参数:
但对于这种情况,您可以实现自定义属性:
用法:
以及
TestCaseSourceAttribute
的类似自定义:用法:
C# 11.0 更新:
从 C# 11.0 开始,您可以指定通用属性。这使得使用通用
[TestCase<...>]
属性成为可能,其方式与OP想要的完全相同:所以最后,现在支持:
NUnit test methods actually can be generic as long as the generic type arguments can be inferred from parameters:
If the generic arguments cannot be inferred, the test runner will not have a clue how to resolve type arguments:
But for this case you can implement a custom attribute:
Usage:
And a similar customization for
TestCaseSourceAttribute
:Usage:
Update for C# 11.0:
Starting with C# 11.0 you can specify generic attributes. This makes possible to use generic
[TestCase<...>]
attributes exactly the same way as the OP wanted:So finally, this is now supported:
我今天有机会做类似的事情,并且对使用反射不满意。
我决定利用 [TestCaseSource],将测试逻辑作为测试上下文委托给通用测试类,固定在非通用接口上,并从各个测试中调用该接口(我的真实测试在接口中有更多方法,并使用 AutoFixture 设置上下文):
I had occasion to do something similar today, and wasn't happy with using reflection.
I decided to leverage [TestCaseSource] instead by delegating the test logic as a test context to a generic testing class, pinned on a non-generic interface, and called the interface from individual tests (my real tests have many more methods in the interface, and use AutoFixture to set up the context):
您可以自定义 GenericTestCaseAttribute
这是 GenericTestCaseAttribute 的实现
You can make custom GenericTestCaseAttribute
Here is implementation of GenericTestCaseAttribute
C# 中的属性不能是通用的,因此您将无法完全按照您的意愿执行操作。也许最简单的事情是将
TestCase
属性放入使用反射来调用真实方法的辅助方法上。像这样的东西可能会起作用(注意,未经测试):Attributes in C# cannot be generic, so you won't be able to do things exactly as you'd like. Perhaps the easiest thing would be to put
TestCase
attributes onto a helper method which uses reflection to call the real method. Something like this might work (note, untested):首先从测试开始——即使是在测试时也是如此。你想让我做什么?可能是这样的:
然后你可以让你的测试成为一个普通的旧功能测试。没有[测试]标记。
Start with the test first--even when testing. What do you want to do? Probably something like this:
Then you can just make your test a plain old function test. No [Test] marker.
我上周做了类似的事情。这就是我最终得到的结果:
然后是测试本身:
I did something similar last week. Here's what I ended up with:
And then the test itself:
我稍微修改了有人在这里发布的 TestCaseGenericAttribute:
此版本需要所有参数的一个列表,从类型参数开始。用法:
注意:一旦将遗传属性引入到语言中,就可以对此进行改进。 (请参阅https:// learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/generic-attributes)
那时,测试框架本身可能会包含这些属性。
I slightly modified the TestCaseGenericAttribute somebody posted here:
This version expects one list of all parameters, starting with the type parameters. Usage:
Note: this can be improved upon once Genetic Atttributes are introduced to the language. (See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/generic-attributes )
At that point, test frameworks will probably include these attributes themselves.
就像使用返回对象的通用函数进行测试一样?示例:
谢谢
As might be testing with generic functions that return objects?. Example:
Thanks
我编写了自己的
TestCaseGenericAttribute
和TestCaseGenericSourceAttribute
。https://github.com/nunit/nunit/issues/3580
I have written my own
TestCaseGenericAttribute
andTestCaseGenericSourceAttribute
.https://github.com/nunit/nunit/issues/3580
这是
TestCaseSource
的一个,它将把每个源对象转换为泛型:用法:
Here's one for
TestCaseSource
that will convert every source object into generics:Usage:
看起来从 NUnit 4.1 开始,您可以使用 TypeArgs 来执行此操作:
https://docs.nunit.org/articles/nunit/writing-tests/attributes/testcase.html
Looks like as of NUnit 4.1 you can do this with
TypeArgs
:https://docs.nunit.org/articles/nunit/writing-tests/attributes/testcase.html