Rhino Mocks - 模拟返回值更改(即使传递相同的参数)与多次调用的方法

本文关键字:参数 方法 调用 返回值 模拟 Mocks Rhino | 更新日期: 2023-09-27 18:35:01

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

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 实现一个子之外?

Rhino Mocks - 模拟返回值更改(即使传递相同的参数)与多次调用的方法

您可以使用 .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。

只需使用

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

这将在第一次调用期间返回1,在第二次调用期间返回2。至少在犀牛模拟 3.6.0.0 中。

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

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

然后,在测试时,传入模拟的 ITimeProvider,以便控制应用程序感知到的时间流逝。