使用NUnit在派生类中设置?

时间:2009-02-14 11:55:47

标签: nunit

如果我有以下代码:

[TestFixture]
public class MyBaseTest
{
    protected ISessionManager _sessionManager;

    [SetUp]
    public void SetUp() { /* some code that initializes _sessionManager */ }
}

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public void SetUp() { /* some code that initializes _repository */ }

    [Test]
    public void BlogRepository_TestGoesHere() { /* some tests */ }
}

... NUnit不会调用基本的SetUp例程。这是预期的,我本身没有问题。我可以先得到派生的SetUp来调用基本的SetUp,如下所示:

[TestFixture]
public class MyDerivedTest : MyBaseTest
{
    IBlogRepository _repository;

    [SetUp]
    public new void SetUp()
    {
        base.SetUp();
        /* some code that initializes _repository */
    }

这太丑了。如果它是构造函数,我就不必这样做。

我可以使用“模板方法”模式,并具有以下内容:

public void MyBaseTest
{
    abstract void SetUp();

    [SetUp]
    public void BaseSetUp()
    {
        /* base initialization */
        SetUp(); // virtual call
    }
}

我也不是特别喜欢这个。

当他们的测试类需要SetUp时,你会做什么,他们是从另一个需要SetUp的类派生出来的?

5 个答案:

答案 0 :(得分:9)

你必须直接调用这个方法。

   [SetUp]
   public void DerivedSetUp()
   {
      base.BaseSetUp();
      // Do something else
   }

编辑:我没有尝试过,但也许部分方法也可能有效。我宁愿做上面的事情。

Edit2:我刚尝试使用部分方法。它没用。即使它确实如此,我认为调用基类仍然会更容易。

答案 1 :(得分:3)

您明确拥有基类。鉴于NUnit使用[Setup]属性标记测试设置,我认为这对NUnit来说是“正确的事”,因为它遵循通常的语言规则。

当然,NUnit可以搜索基类,并自动调用它们的安装功能,但我认为这对大多数人来说都是相当令人惊讶的。

但是至少有一个单元测试框架使用构造函数进行设置:xUnit.Net。这里,基类设置自动调用,因为这是C#中构造函数的行为。

(但请注意,xUnit.Net建议再次使用测试设置。)

答案 2 :(得分:1)

看起来您希望在任何测试开始之前运行一次设置,而不是在每次测试运行之前运行一次。注释[SetUp]使方法在运行夹具中的每个测试之前运行一次。 [SetUp]不是继承的。

您要使用的注释是[TestFixtureSetUp],在运行灯具中的任何测试之前,它只运行一次。这是以您期望的方式继承的。 :)

请参阅the TextFixtureSetUp docs

答案 3 :(得分:0)

我在Tampa的TDD FireStarter中学到的一种方法是在基类中使用setup方法,然后在基类中使用名为observe的虚方法。然后在setup方法结束时在基类中调用此方法。

然后你要做的是从基类派生的新类,你将覆盖observe方法。这种情况下的技巧是你想要执行基类的Setup方法,而子类没有Setup方法。原因是您在observe方法中拥有的代码只是子测试类所需的其他内容。

这种方法对我很有用,但有一个问题是测试运行器会想要执行基类测试,所以我要做的就是将测试从基类移动到派生的新类中如果我有的话,从基地开始。

答案 4 :(得分:-1)

以下适用于MbUnit。它也可以在NUnit中工作。

[TestFixture]
public abstract class Base {
    [SetUp]
    public virtual void SetUp() {
        //Some stuff.
    }
}

public class Derived : Base {
    public override void SetUp() {
        base.SetUp();
        //Some more stuff.
    }
    [Test]
    public virtual void Object_WhenInACertainState_WhenAMethodIsCalled_Throws() {
        //Create and set state on the object.
        //Call the method.
        //Assert the method threw.
    }
}