RhinoMocks - mocking a method whose return value changes (even when passed the same parameter) with multiple calls

妖精的绣舞 提交于 2019-12-03 15:00:50

问题


I'm looking to find out how I can mock a method that returns a different value the second time it is called to the first time. For example, something like this:

public interface IApplicationLifetime
{
    int SecondsSinceStarted {get;}
}

[Test]
public void Expected_mock_behaviour()
{
    IApplicationLifetime mock = MockRepository.GenerateMock<IApplicationLifetime>();

    mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once();
    mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once();

    Assert.AreEqual(1, mock.SecondsSinceStarted);
    Assert.AreEqual(2, mock.SecondsSinceStarted);
}

Is there anything that makes this possible? Besides implementing a sub for the getter that implements a state machine?

Cheers fellas,

Alex


回答1:


You can intercept return values with .WhenCalled method. Note that you still need to provide value via .Return method, however Rhino will simply ignore it if ReturnValue is altered from method invocation:

int invocationsCounter = 1;
const int IgnoredReturnValue = 10;
mock.Expect(m => m.SecondsSinceLifetime)
    .WhenCalled(mi => mi.ReturnValue = invocationsCounter++)
    .Return(IgnoredReturnValue);

Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(1));
Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(2));

Edit:

Digging around a bit more, it seems that .Repeat.Once() does indeed work in this case and can be used to achieve same result:

mock.Expect(m => m.SecondsSinceStarted).Return(1).Repeat.Once();
mock.Expect(m => m.SecondsSinceStarted).Return(2).Repeat.Once();
mock.Expect(m => m.SecondsSinceStarted).Return(3).Repeat.Once();

Will return 1, 2, 3 on consecutive calls.




回答2:


Simply use

mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once();
mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once();

This will return 1 during first call, and 2 during second call. At least on RhinoMocks 3.6.0.0




回答3:


Is time the determining factor in what the method returns? If so, I would try to abstract out the time passage so you have direct control over it in your tests.

Something like an interface called ITimeProvider with a member called GetElapsedTime() and then create a default implementation to use throughout your application.

Then when you are testing, pass in a mocked ITimeProvider so you control what is perceived by your application to be time passed.



来源:https://stackoverflow.com/questions/10720908/rhinomocks-mocking-a-method-whose-return-value-changes-even-when-passed-the-s

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