犀牛模拟覆盖存根可能吗?

时间:2010-02-19 08:35:41

标签: unit-testing rhino-mocks

我有这个问题,这可能是Rhino Mocks 3.5中的一个错误:

stubObj = MockRepository.GenerateStub(IObject);

stubObj.Stub(a=>a.Get()).Return (Guid.Empty); //1.stub
stubObj.Stub(a=>a.Get()).Return (Guid.NewGuid()); //2.stub, should overwrite the first one?

这样:

var value = stubObj.Get(); 

返回Guid.Empty,这是正确的行为吗?

6 个答案:

答案 0 :(得分:8)

如果你想将空guid返回已知的次数,你唯一需要做的就是告诉RhinoMocks多少次重复它,例如以下测试通过:

[Test]
    public void MultipleStubsTest()
    {
        var testMock = MockRepository.GenerateMock<ITest>();
        testMock.Stub(x => x.Get()).Return(Guid.Empty).Repeat.Once();
        testMock.Stub(x => x.Get()).Return(Guid.NewGuid());

        Assert.AreEqual(Guid.Empty, testMock.Get());
        Assert.AreNotEqual(Guid.Empty, testMock.Get());
    }

如果你不知道在guid改变之前会调用多少次Get(),那么你总是可以使用.Do()并在那里编码(如果你需要更多细节,请告诉我)。< / p>

答案 1 :(得分:1)

您刚刚为两个单独的调用编写了Stub对象。如果再次调用stubObj.Get,则应该得到Guid.NewGuid生成的内容。您可以为任意数量的不同类型的调用准备假对象。出于这个原因,期望对给定调用的最后.Stub调用替换该调用的先前.Stub绑定是没有意义的。

在你的测试代码中,它应该简洁明了,绝不应该出现你需要以你想要的方式“撤消”这种模拟编程的情况。

如果需要返回的是一个有条件的东西,它会根据你对这段代码的多次调用的测试代码的其他部分而变化,你想要的最后一件事就是让读者想出你的意思。如果它是有条件的,你应该说清楚。

然后,当你说清楚的时候,重构它,因为你不应该在测试中有条件逻辑(参见xUnit测试模式)

答案 2 :(得分:1)

答案 3 :(得分:0)

以下测试应该通过:

// arrange
var stubObj = MockRepository.GenerateStub<IObject>();
stubObj.Stub(a => a.Get())
       .Return(Guid.Empty);
// act
var value = stubObj.Get();
// assert
Assert.AreEqual(Guid.Empty, value);

如果你想返回一个新指南:

// arrange
var stubObj = MockRepository.GenerateStub<IObject>();
stubObj.Stub(a => a.Get())
       .Return(Guid.NewGuid());
// act
var value = stubObj.Get();
// assert
Assert.AreNotEqual(Guid.Empty, value);

答案 4 :(得分:0)

如果合适,您可以选择重置所有期望。

    public interface IObject { Guid Get(); }

    [Test]
    public void OverwriteStubTest()
    {
        Guid ret = Guid.NewGuid();
        var stub = MockRepository.GenerateMock<IObject>();

        stub.Stub(a => a.Get()).Return(Guid.Empty);
        Assert.AreEqual(Guid.Empty, stub.Get());

        //Reset all expectations on this mock object
        stub.BackToRecord(); 
        stub.Stub(a => a.Get()).Return(ret);
        stub.Replay();
        Assert.AreEqual(ret, stub.Get());
    }

答案 5 :(得分:-1)

是的,这是预期的行为。以这种方式编写期望/存根告诉模拟框架在第一次调用Get()方法时返回Guid.Empty,并在第二次调用它时返回Guid.NewGuid()。

以下几种方法可以用第二种方法“覆盖”第一个期望:How to change behaviour of stubs?