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 实现一个子之外?
您可以使用 .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,以便控制应用程序感知到的时间流逝。