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

标签 c# unit-testing mocking nunit rhino-mocks

我最近开始使用 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/

相关文章:

c# - 这真的是 WPF 的 SaveFileDialog.FileName 中需要的行为吗?

c# - 将 Action 结果绑定(bind)到 MVC5 中的按钮

java - 在集成测试中进行模拟是否被认为是一种好习惯?

c# - 使用 OR 条件断言

perl - 是否可以在 perl 中模拟或修补输入参数?

Ruby rspec 模拟一个类

python - 如何模拟 celery 任务的类方法

c# - XElement.Parse NotSuportedException

c# - 如何修剪 IP 地址以获得它的前 3 部分?

c++ - 强制一个特定的构造函数只在某些代码中使用,别处