我有一个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()方法中的还没有为我提供一个干净的模拟模型实例,开始我的测试吗?
答案 0 :(得分:3)
不,NUnit不为每个测试用例创建fixture类的新实例。创建单个实例,然后为每个测试重复使用。这与其他测试框架不同,但它是NUnit一直有效的方式(自2000年以来)。
这意味着您必须小心如何使用对象状态。 1.使用尽可能少的状态。 2.使用SetUp进行初始化,使用TearDown进行清理。
Per @ David的评论...... NSubstitute将自动替换返回接口的成员。请参阅递归模拟。我认为这解释了为什么model.currentlyDisplayedMessage被初始化为新替换的模型。