我何时使用TestFixtureSetUp属性而不是默认构造函数?

时间:2008-10-17 15:48:42

标签: c# unit-testing nunit

NUnit文档没有告诉我何时使用TestFixtureSetup的方法以及何时在构造函数中进行设置。

public class MyTest
{
    private MyClass myClass;

    public MyTest()
    {
        myClass = new MyClass();
    }

    [TestFixtureSetUp]
    public void Init()
    {
        myClass = new MyClass();
    }
}

是否有关于TestFixtureSetup与默认构造函数的好/坏做法,或者没有任何区别?

9 个答案:

答案 0 :(得分:64)

为什么需要在测试类中使用构造函数?

我使用[SetUp][TearDown]标记的方法在每次测试之前和之后执行代码,同样[TestFixtureSetUp][TestFixtureTearDown]标记的方法只能执行代码一旦在夹具中的所有测试之前和之后都已经运行。

我猜你可以用[TestFixtureSetUp]代替一个构造函数(尽管我没有尝试过),但这似乎只是打破了标记方法所提供的明确约定。

答案 1 :(得分:15)

我认为这是nUnit团队尚未解决的问题之一。但是,有一个很好的xUnit project看到了这个确切的问题,并决定在test fixture initialization上使用构造函数是一件好事。

对于nunit,我在这种情况下的最佳做法是使用文档中描述的TestFixtureSetUpTestFixtureTearDownSetUpTearDown方法。

我认为当我没有将nUnit测试夹具视为普通类时,它也有帮助,即使您使用该构造定义它。我认为它们是固定装置,这让我超越了心理障碍,让我忽略了这个问题。

答案 2 :(得分:12)

您可以在构造函数中使用[TestFixtureSetup]做的一件事是从[TestFixture]接收参数。

如果要对测试夹具进行参数化,则必须至少使用构造函数某些的设置。到目前为止,我只使用它进行集成测试,例如用于测试具有多个数据提供者的数据访问层:

[TestFixture("System.Data.SqlClient",
  "Server=(local)\\SQLEXPRESS;Initial Catalog=MyTestDatabase;Integrated Security=True;Pooling=False"))]
[TestFixture("System.Data.SQLite", "Data Source=MyTestDatabase.s3db")])]
internal class MyDataAccessLayerIntegrationTests
{
    MyDataAccessLayerIntegrationTests(
        string dataProvider,
        string connectionString)
    {
        ...
    }
}

答案 3 :(得分:9)

我经常想知道[TestFixtureSetUp]的需要是什么,因为有一个简单的,易于理解的第一类语言结构完全相同的事情。

我的偏好是使用构造函数,以利用readonly关键字确保成员变量无法重新初始化。

答案 4 :(得分:9)

构造函数和标有[TestFixtureSetUp]属性的方法之间存在差异。根据NUnit文档:

  

建议构造函数没有任何副作用,因为NUnit可能会在会话过程中多次构造对象。

因此,如果您有任何昂贵的初始化,最好使用TestFixtureSetUp

答案 5 :(得分:4)

[TestFixtureSetUp][TestFixtureTearDown]适用于整个测试类。只运行一次。

每个测试方法(测试)都有

[SetUp][TearDown]。每次测试都会运行。

答案 6 :(得分:3)

构造函数和TestFixtureSetUp之间的一个重要区别是,至少在NUnit 2中,构造函数代码实际上是在测试枚举上执行的,而不仅仅是测试运行,所以基本上你想要将ctor代码限制为只填充readonly,即参数值。任何导致副作用或任何实际工作的东西都需要包装在Lazy中或在TestFixtureSetUp / OneTimeSetUp中完成。因此,您可以将构造函数视为配置测试的地方。而TestFixtureSetUp是测试夹具(测试运行前所需的系统初始状态)初始化的地方。

答案 7 :(得分:2)

我认为我有一个负面的好答​​案 - 使用构造函数而不是属性的原因是当你在测试类之间有继承时。

只会调用一个用[TestFixtureSetup]注释的方法(仅在具体类上),但其他夹具初始化程序不会。在这种情况下,我宁愿将初始化放在构造函数中,该构造函数具有明确定义的继承语义:)

答案 8 :(得分:-2)

构造函数和SetUp方法的使用方式不同:
构造函数只运行一次 但是,在执行每个测试用例之前,SetUp方法会多次运行。