NUnit 3.x - TestCaseSource for descendant test classes
我目前有一组单元测试,它们对于许多 Rest API 端点都是一致的。假设类是这样定义的。
1 2 3 4 5 6 7 8 | public abstract class GetAllRouteTests<TModel, TModule> { [Test] public void HasModels_ReturnsPagedModel() { // Implemented test } } |
实现的测试夹具看起来像:
1 2 | [TestFixture(Category ="/api/route-to-test")] public GetAllTheThings : GetAllRouteTests<TheThing, ModuleTheThings> { } |
这使我能够在所有 GET all/list 路由上运行许多常见测试。这也意味着我有直接链接到正在测试的模块的类,以及 Resharper / Visual Studio / CI"正常工作"中的测试和代码之间的链接。
挑战在于,有些路由需要查询参数才能通过路由代码测试其他路径;
例如/api/route-to-test?category=big.
由于 [TestCaseSource] 需要静态字段、属性或方法,因此似乎没有很好的方法来覆盖要传递的查询字符串列表。我想出的最接近的东西似乎是一个黑客。即:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public abstract class GetAllRouteTests<TModel, TModule> { [TestCaseSource("StaticToDefineLater")] public void HasModels_ReturnsPagedModel(dynamic args) { // Implemented test } } [TestFixture(Category ="/api/route-to-test")] public GetAllTheThings : GetAllRouteTests<TheThing, ModuleTheThings> { static IEnumerable<dynamic> StaticToDefineLater() { // yield return all the query things } } |
这是因为静态方法是为实现的测试类定义的,并且由 NUnit 找到。巨大的黑客。对于使用抽象类的其他人来说也是有问题的,因为他们需要"知道"将"StaticToDefineLater"实现为静态的东西。
我正在寻找一种更好的方法来实现这一目标。似乎在 NUnit 3.x 中删除了非静态 TestCaseSource 源,所以它已经出局了。
提前致谢。
注释:
- GetAllRouteTests<> 实现了许多测试,而不仅仅是显示的那个。
- 在一个测试中遍历所有路线将"隐藏"所涵盖的内容,因此希望避免这种情况。
我解决类似问题的方法是拥有一个实现 IEnumerable(NUnit 的另一个可接受的源)的基源类,考虑这种设计是否适合您的用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // in the parent fixture... public abstract class TestCases : IEnumerable { protected abstract List<List<object>> Cases { get; } public IEnumerator GetEnumerator() { return Cases.GetEnumerator(); } } // in tests private class TestCasesForTestFoobar : TestCases { protected override List<List<object>> Cases => /* sets of args */ } [TestCaseSource(typeof(TestCasesForTestFoobar))] public void TestFoobar(List<object> args) { // implemented test } |