Changing previously stubbed calls with Rhino Mocks

There are occasionally times when I want to stub a call to return different values at different times in my test. I try and avoid this, as it generally means I’m writing procedural code and violating the Tell Don’t Ask principle, but there are times when it’s necessary (say, writing procedural steps for an integration test).

Anyway, I’ve tended to struggle with this when using Rhino Mocks, and end up randomly trying various forms of repeats, such as Repeat.AtLeastOnce() or Repeat.Any(), before I get it to work.

I recently found a better way thanks to a thread on StackOverflow: just use a closure.

public interface IDoStuffWithInts { int GetAnInt(); }

[Test]
public void Change_return_value() {
    int valueToReturn = 0;
    var stub = MockRepository.GenerateStub<IDoStuffWithInts>();
    stub.Stub(x => x.GetAnInt())
        .Return(0)
        .WhenCalled(x => x.ReturnValue = valueToReturn);

    valueToReturn = 7;
    Assert.AreEqual(stub.GetAnInt(), valueToReturn);
    valueToReturn = 11;
    Assert.AreEqual(stub.GetAnInt(), valueToReturn);
}

Unfortunately you need to set a dummy return value first, but you can then override that using WhenCalled. This makes it easy to change the stubbed value by changing the variable. I’ve found it useful to sometimes wrap this in a helper method, such as MakeStuffDoerReturn(int value).

Hardly ground-breaking I know, but hopefully it will save someone else a bit of pain. :)

Comments