Rhino模拟两次存根,相同的函数不能像预期的那样工作

本文关键字:不能 函数 工作 模拟 存根 两次 Rhino | 更新日期: 2023-09-27 18:18:21

我最近开始使用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();
}

有人知道为什么Rhino存根会这样做,更重要的是我如何以最干净的方式解决它?

Rhino模拟两次存根,相同的函数不能像预期的那样工作

当你在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);,然后任何东西都可以工作。

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

Option1:清空模拟

// clear expectations, an enum defines which
_worker.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_worker.Replay();

Option2:限制行为

_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...

,然后在test方法中添加一个循环:

for(...; i < num of time; ...)
    _worker.DoWork();

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