有没有办法让每个类运行一次SetUpFixture而不是每个名称空间运行一次?

脚本
首先,我是新手测试 – 所以请耐心等待。 在我的测试项目中 ,有一个Controllers文件夹。 Controllers文件夹可能包含ControllerATest.cs,ControllerBTest.cs和ControllerCTest.cs。 因为我的命名空间与我的文件夹结构一致,所以它们共享命名空间MyProject.Tests.Controllers。

根据我在NUnit SetUpFixture文档中读到的内容,此命名空间内的[SetUpFixture]将为整个命名空间运行一次。 也就是说,如果我一次运行所有控制器测试 – SetUpFixture将只执行一次。

问题
正如我所说,每个控制器测试共享一个命名空间。 SetUpFixtures适用于整个命名空间。 如果我希望每个控制器都有自己 SetUpFixture怎么办? 当SetUpFixtures应用于整个名称空间时,这是一个问题。 我想要的是执行一次的东西,而不是每次测试。 我在SetUpFixture的SetUp中做的一件事就是实例化一个控制器。 当然,我可以在SetUpFixture中实例化所有3个控制器,但是当我可能只测试ControllerC时,这看起来很难看。 这真的不干净。 因此,我想要一个仅适用于它出现的类的SetUpFixture,例如ControllerCTests。

根据我的阅读,NUnit似乎无法实现这一特定function。 如果NUnit无法实现,那么我认为这不是常见的情况。 如果这不是一个常见的情况,我做错了。 我的问题是,什么? 也许我的测试结构已关闭,需要更改。 或者NUnit可能有可能吗?


我想要的结构的一个例子:

namespace MyProject.Tests.Controllers { public class ControllerATests { private static IMyProjectRepository _fakeRepository; private static ControllerA _controllerA; [SetUpFixture] public class before_tests_run { [SetUp] public void ControllerASetup() { _fakeRepository = FakeRepository.Create(); _controllerA = new ControllerA(_fakeRepository); } } [TestFixture] public class when_ControllerA_index_get_action_executes { [Test] public void it_does_something() { // } [Test] public void it_does_something_else() { // } } } public class ControllerBTests { private static IMyProjectRepository _fakeRepository; private static ControllerB _controllerB; [SetUpFixture] public class before_tests_run { [SetUp] public void ControllerBSetup() { _fakeRepository = FakeRepository.Create(); _controllerB = new ControllerB(_fakeRepository); } } [TestFixture] public class when_ControllerB_index_get_action_executes { [Test] public void it_does_something() { // } [Test] public void it_does_something_else() { // } } } } 

我试过的事情

  • 将每个.cs文件移动到其自己的文件夹中,因此它们具有不同的命名空间。 从技术上讲,这解决了这个问题,只有一堆子文件夹在每个子文件夹中只有1个项目,这看起来有点难看。 丑陋,并且将不再符合我的父项目的结构。 但是 – 也许这是要走的路。
  • 不在SetUpFixture SetUp中实例化我的控制器,而是在TestFixture SetUp中执行它,以便为每个测试(例如:5个测试= 5个单独的实例)实例化一个新实例,而不是每个类或命名空间实例化一次。 虽然看起来我只能创建1个实例,但我应该这样做。

建议?

对Controller类中的方法使用TestFixtureSetUpAttribute

 [TestFixture] public class when_ControllerA_index_get_action_executes { [TestFixtureSetUp] public void FixtureSetUp() { // this code runs once no matter how many tests are in this class } [Test] public void it_does_something() { // ... } } 

从文档:

此属性在TestFixture内部使用,以提供在执行夹具中的任何测试之前执行一次的单个函数集。

这里,“TestFixture”是class同义词。

对于NUnit 3.4.1及更高版本,请使用OneTimeSetUp :

 [TestFixture] public class MyTest { [OneTimeSetUp] public void Setup() { // one time setup code for this class } } 

顺便说一句, TestFixtureSetUp已被弃用。