RhinoMocks - 模拟一个方法,其返回值随多次调用而改变(即使传递相同的参数)

时间:2012-05-23 13:25:59

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

我正在寻找如何模拟第二次调用第二次返回不同值的方法。例如,像这样:

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);
}

有什么能让这成为可能吗?除了为实现状态机的getter实现一个sub?

干杯fellas,

亚历

3 个答案:

答案 0 :(得分:34)

您可以使用.WhenCalled方法拦截返回值。请注意,您仍然需要通过.Return方法提供值,但是如果从方法调用中更改ReturnValue,Rhino将忽略它:

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));

修改

进一步挖掘,似乎.Repeat.Once() 确实确实在这种情况下起作用,可用于实现相同的结果:

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();

连续呼叫将返回1,2,3。

答案 1 :(得分:6)

只需使用

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

这将在第一次通话期间返回1,在第二次通话期间返回2。至少在RhinoMocks 3.6.0.0上

答案 2 :(得分:0)

时间是方法返回的决定因素吗?如果是这样,我会尝试抽象出时间段,以便在测试中直接控制它。

类似于名为ITimeProvider的接口,其中包含一个名为GetElapsedTime()的成员,然后创建一个在整个应用程序中使用的默认实现。

然后,当您进行测试时,传入一个模拟的ITimeProvider,以便您控制应用程序感知的时间过去。