如何使用依赖于运行的TestSetup方法的NUnit测试用例?

时间:2017-01-23 14:59:02

标签: c# unit-testing nunit

我正在使用NUnit 2为C#编写一些单元测试。我的环境是安装了Resharper的Visual Studio 2015 Professional。

我遇到的问题是我尝试使用TestCaseSourceAttribute创建一些参数化测试。在简单的情况下,我可以创建这样的测试,它可以正常工作:

[Test, TestCaseSource(nameof(MyTestCases))]
public void MyTest(string name) {
    Assert.IsFalse(String.IsNullOrEmpty(name));
}

private static IEnumerable<TestCaseData> MyTestCases {
    get {
        yield return new TestCaseData("test");
        yield return new TestCaseData("123");
    }
}

但是,当我尝试实例化必须从数据库实体映射的类型或在初始化过程中检查数据库时,测试运行器会忽略该测试。例如:

[Test, TestCaseSource(nameof(MyTestCases))]
public void MyTest(MyMappedType instance) {
    Assert.IsTrue(instance.SomeProperty);
}

private static IEnumerable<TestCaseData> MyTestCases {
    get {
        yield return new TestCaseData(GetAnInstanceOfMyMappedType());
        yield return new TestCaseData(GetADifferentInstanceOfMyMappedType());
    }
}

MyMappedType的实例化如果在测试体中本身就可以正常工作,但如果任何测试用例实例化它,则忽略测试。

我可以让这些测试以参数化方式工作吗?有关此的任何文档参考?

更新

问题似乎是由于测试用例属性中的某些代码依赖于已经运行的类TestSetup方法。有没有办法在初始化每个测试用例之前而不是之后进行设置运行?

2 个答案:

答案 0 :(得分:2)

不,在生成测试之前无法调用您的设置。

此外,虽然可以在TestCaseSource方法中实例化对象,但是一旦方法返回,这些对象就会超出范围,除非保存在某个地方,例如静态成员。当然,这不是一个很好的做法。

重写TestCaseSource以提供可用于在运行时创建所需对象的参数,如整数和字符串。

如果你想每个夹具只创建一次这些对象,请使用OneTimeSetUp而不是SetUp,并使用参数化夹具来保存创建它们所需的参数。

答案 1 :(得分:0)

使用C#编译器的一个属性,我们可以找到解决这个问题的方法。流程如下:

  1. 在静态方法中检索数据
  2. 静态方法放在类的所有其他成员之前
  3. 需要注意的是,source 每次执行仅完成一次(这是此方法的局限性之一)
  4. 测试用例可以使用之前生成的数据。