Rhino mocks stubbing 两次相同的函数没有按预期工作

Rhino mocks stubbing twice the same function doesn't work as expected

我最近开始使用 Rhino,遇到了一个我无法克服的非常意外的行为。

问题是我有一个存根基础结构,在我的一项测试中,我需要将一个预定义存根(在我的基础结构中)更改为 return 与默认值不同的值。

我在以下代码中重现了该问题:

[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 存根会这样,更重要的是我怎样才能以最干净的方式解决它?

当您在 RhinoMocks 中指定一个假对象的行为时没有任何约束(RepeatOnce 等),该行为将保留并且您将无法覆盖它。(实际上选项 1 显示你怎么能...)

在您的情况下,您在 Setup 方法中指定了特定行为:

_worker.Stub(w=>w.DoWork()).Return(0);

以上行将在_worker.Stub(w => w.DoWork()).Return(expected);之前执行。

SetUp / TestInitialize 属性的最佳做法是在它们内部分组 您想要在 all 中应用的设置测试方法.

默认情况下,任何具有 return 值的方法 return 都是 default(T),因此您可以删除 _worker.Stub(w=>w.DoWork()).Return(0); 然后任何方法都可以工作。

如果您的实际情况更复杂:

选项 1: 清除 mock

// 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();

Option3: 创建一个新的fake和CUT(class under test)