Ordering method return values with Rhino-Mock stubs

╄→尐↘猪︶ㄣ 提交于 2019-12-30 06:11:12

问题


I've started experimenting with Rhino-Mocks (3.6) while reading Roy Osherove's The Art of Unit Testing. He has an example that demonstrates that a mocked method can be scripted to return different results when called twice with the same parameter:

   [Test]
    public void ReturnResultsFromMock()
    {
        MockRepository repository = new MockRepository();
        IGetRestuls resultGetter = repository.DynamicMock<IGetRestuls>();
        using(repository.Record())
        {
            resultGetter.GetSomeNumber("a");
            LastCall.Return(1);

            resultGetter.GetSomeNumber("a");
            LastCall.Return(2);

            resultGetter.GetSomeNumber("b");
            LastCall.Return(3);

        }

        int result = resultGetter.GetSomeNumber("b");
        Assert.AreEqual(3, result);

        int result2 = resultGetter.GetSomeNumber("a");
        Assert.AreEqual(1, result2);

        int result3 = resultGetter.GetSomeNumber("a");
        Assert.AreEqual(2, result3);
    }

This works fine. But when I try the same thing with a Stub, and a method that accepts and returns a string, I am not able to generate the second return value:

    [Test]
    public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived()
    {
        MockRepository mocks = new MockRepository();
        IMessageProvider stub = mocks.Stub<IMessageProvider>();

        using (mocks.Record())
        {
            stub.GetMessageForValue("a");
            LastCall.Return("First call");
            stub.GetMessageForValue("a");
            LastCall.Return("Second call");
        }

        Assert.AreEqual("First call", stub.GetMessageForValue("a"));
        Assert.AreEqual("Second call", stub.GetMessageForValue("a"));
    }
}

public interface IMessageProvider
{
    string GetMessage();
    string GetMessageForValue(string value);
}

This test is failing, because "First Call" is received for both calls. I've tried several wrinkles of syntax (Using mocks.Ordered(), SetResult, Expect etc.), but am still unable to get the second result to appear.

Am I doing something wrong, or is this a limitation with Rhino-Mocks? I've checked this blog post, but the suggested syntax did not resolve my issue.


回答1:


The bit you're missing is to tell the stub that the first value should only be returned once:

...
using (mocks.Record())
{
    stub.GetMessageForValue("a");
    LastCall.Return("First call").Repeat.Once();
    stub.GetMessageForValue("a");
    LastCall.Return("Second call");
}

Of course your "Second call" really means "Second-or-subsequent call" unless you impose other restrictions with Repeat.

You might also consider using the newer Arrange, Act, Assert (AAA) syntax RhinoMocks now offers:

[Test]
public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived()
{
    IMessageProvider stub = MockRepository.GenerateStub<IMessageProvider>();

    stub.Expect(mp => mp.GetMessageForValue("a"))
        .Return("First call")
        .Repeat.Once();
    stub.Expect(mp => mp.GetMessageForValue("a"))
        .Return("Second call");

    Assert.AreEqual("First call", stub.GetMessageForValue("a"));
    Assert.AreEqual("Second call", stub.GetMessageForValue("a"));
}

It's a little more concise and generally saves you from having to worry about the record-playback-assert state of the stub. Derick Bailey wrote an article about using Repeat on Los Techies. It also happens to use the AAA syntax).




回答2:


I think if you are working with stubs, using Expect does not fit as you do not want an expectation but a replacement for your dependency.

So I believe if you use the stub syntax it makes more sense:

stub.Stub.(s=>s.GetMessageForValue("a"))
                            .Return("First call").Repeat.Once(); 

stub.Stub.(s=>s.GetMessageForValue("a"))
                            .Return("Second call").Repeat.Any;


来源:https://stackoverflow.com/questions/5609589/ordering-method-return-values-with-rhino-mock-stubs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!