NUnit是否重新实例化每个测试之间标记为TestFixtures的类?

时间:2017-04-11 15:08:15

标签: c# nunit nsubstitute

我有一个TestFixture标记类,它是单元测试名为' HideCurrentTitleBarMessageTask'的类的功能。

在这个类中,我使用替换来模拟[Setup]方法中的接口,并且在测试类的一些测试中,我设置了一个模拟接口成员的返回结果。

[TestFixture]
public class TestClass_A {

    private ITitleBarMessageModel model;
    private ITitleBarMessage message;
    private HideCurrentTitleBarMessageTask task;
    private bool taskCompleteFired;


    [SetUp]
    public void SetUp() {
        taskCompleteFired = false;
        model = Substitute.For<ITitleBarMessageModel>();
        message = Substitute.For<ITitleBarMessage>();
        //model.currentlyDisplayedMessage = null;
        task = new HideCurrentTitleBarMessageTask();
        task.Init(model);
        task.Completed += (t) => { taskCompleteFired = true; };
    }

    [Test]
    public void Test_A() {
        task.Execute();
        Assert.That(taskCompleteFired, Is.True);
    }

    [Test]
    public void Test_B() {
        model.currentlyDisplayedMessage.Returns(message);
        task.Execute();
        message.Received(1).Hide();
        Assert.That(taskCompleteFired, Is.False);
    }
}

HideCurrentTitleBarMessageTask&#39; s执行功能如下所示

public override void Execute() {
        if (model.currentlyDisplayedMessage != null) {
            //Some irrelevant stuff
        } else {
            Completed(this);
        }
}

请注意,仅在Test_B中,我是否使用 model.currentlyDisplayedMessage 设置返回值。

如果我在Test_A的第1行中断点,我在调试器中看到 model.currentlyDisplayedMessage 不为空,但实际上已分配。什么时候不应该。虽然大概是方法 SetUp 被称为先行,而行

model = Substitute.For<ITitleBarMessageModel>();

已执行,有效地将新的模拟实例重新分配给模型。 这会导致Test_A失败。

现在,请注意注释掉的行

//model.curentlyDisplayedMessage = null;
在SetUp方法中

。取消注释,通过将模型中的引用显式设置为null来解决问题。 (我也假设在[TearDown]标记方法中可以实现相同的结果)。

NUnit是否不会消除TestClass并在测试之间从头开始?

如果没有,有人可以告诉我为什么打电话给

model = Substitute.For<ITitleBarMessageModel>();
在SetUp()方法中的

还没有为我提供一个干净的模拟模型实例,开始我的测试吗?

1 个答案:

答案 0 :(得分:3)

不,NUnit不为每个测试用例创建fixture类的新实例。创建单个实例,然后为每个测试重复使用。这与其他测试框架不同,但它是NUnit一直有效的方式(自2000年以来)。

这意味着您必须小心如何使用对象状态。 1.使用尽可能少的状态。 2.使用SetUp进行初始化,使用TearDown进行清理。

Per @ David的评论...... NSubstitute将自动替换返回接口的成员。请参阅递归模拟。我认为这解释了为什么model.currentlyDisplayedMessage被初始化为新替换的模型。