我最近开始使用 Rhino,遇到了一个我无法克服的非常意外的行为。
问题是我有一个 stub 基础结构,在我的一项测试中,我需要更改预定义 stub 之一(在我的基础结构中)以返回与默认值不同的值。
我在下面的代码中重现了这个问题:
[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();
}
有人知道为什么 Rhino stub 会以这种方式运行,更重要的是我怎样才能以最干净的方式解决它?
最佳答案
当您在 RhinoMocks
中指定一个假对象的行为时没有任何约束(RepeatOnce 等),该行为将保留并且您将无法覆盖它。(实际上是选项 1显示你如何...)
在您的情况下,您在 Setup
方法中指定了一个特定的行为:
_worker.Stub(w=>w.DoWork()).Return(0);
以上行将在 _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();
选项2:限制行为
_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...
然后在测试方法中添加一个循环:
for(...; i < num of time; ...)
_worker.DoWork();
选项 3:创建一个新的伪造和 CUT(被测类)
关于c# - Rhino mocks stubbing 两次相同的函数没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33195228/