sil*_*ver 5 c# nunit unit-testing rhino-mocks mocking
我最近开始使用Rhino,遇到了一种非常意想不到的行为,我无法克服。
问题是我有一个存根基础设施,在我的一项测试中,我需要更改预定义存根之一(在我的基础设施中)以返回与默认值不同的值。
我在以下代码中重现了该问题:
[TestFixture]
public class UnitTest1
{
private IWorker _worker;
[SetUp]
void Setup()
{
_worker = MockRepository.GenerateStub<IWorker>();
_worker.Stub(w=>w.DoWork()).Return(0);
}
[Test]
public void DoWork_StubbingFunctionTwice_CallingTheLastStub()
{
int expected = 1;
_worker.Stub(w => w.DoWork()).Return(expected);
int actual =_worker.DoWork();
Assert.AreEqual(expected, actual);
}
}
public interface IWorker
{
int DoWork();
}
Run Code Online (Sandbox Code Playgroud)
有人知道为什么犀牛存根会这样,更重要的是我怎样才能以最干净的方式解决它?
当您在没有任何约束(RepeatOnce 等)的情况下在假对象上指定行为时,RhinoMocks该行为将保留并且您将无法覆盖它。(实际上选项 1 显示了如何可以...)
在您的情况下,您在方法中指定特定行为Setup:
_worker.Stub(w=>w.DoWork()).Return(0);
Run Code Online (Sandbox Code Playgroud)
上面的行将在 之前执行_worker.Stub(w => w.DoWork()).Return(expected);。
SetUp/属性的最佳实践是仅将您想要在所有测试方法TestInitialize中应用的设置分组到其中。
默认情况下,任何具有返回值的方法都会返回,default(T)因此您可以删除_worker.Stub(w=>w.DoWork()).Return(0);,然后任何事情都会起作用。
如果您的实际情况更复杂:
选项1:清除模拟
// clear expectations, an enum defines which
_worker.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_worker.Replay();
Run Code Online (Sandbox Code Playgroud)
选项2:限制行为
_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...
Run Code Online (Sandbox Code Playgroud)
然后在测试方法中添加一个循环:
for(...; i < num of time; ...)
_worker.DoWork();
Run Code Online (Sandbox Code Playgroud)
选项3:创建一个新的假货并CUT(被测类)