Rhino Mocks:在存根上为方法重新分配新结果
时间:2020-03-06 14:37:23 来源:igfitidea点击:
我知道我可以这样做:
IDateTimeFactory dtf = MockRepository.GenerateStub<IDateTimeFactory>(); dtf.Now = new DateTime(); DoStuff(dtf); // dtf.Now can be called arbitrary number of times, will always return the same value dtf.Now = new DateTime()+new TimeSpan(0,1,0); // 1 minute later DoStuff(dtf); //ditto from above
如果不是IDateTimeFactory.Now是属性而是方法IDateTimeFactory.GetNow(),该怎么办,我该怎么做?
根据以下犹大的建议,我将我的SetDateTime helper方法重写如下:
private void SetDateTime(DateTime dt) {
Expect.Call(_now_factory.GetNow()).Repeat.Any();
LastCall.Do((Func<DateTime>)delegate() { return dt; });
}
但它仍然抛出" ICurrentDateTimeFactory.GetNow();的结果已经设置。"错误。
再加上它仍然无法与存根一起使用。
解决方案
我们可以使用Expect.Call完成此操作。这是使用记录/播放模型的示例:
using (mocks.Record())
{
Expect.Call(s.GetSomething()).Return("ABC"); // 1st call will return ABC
Expect.Call(s.GetSomething()).Return("XYZ"); // 2nd call will return XYZ
}
using (mocks.Playback())
{
DoStuff(s);
DoStuff(s);
}
好的,所以我的第一个答案对我们不起作用,因为GetSomething可能会被多次调用,而我们却不知道调用了多少次。
我们在这里遇到了一些复杂的情况-方法调用的数量未知,但是在调用DoSomething之后会有不同的结果-我建议我们将单元测试简化一些,否则我们将不得不为单元测试准备单元测试。 :-)
失败了,这是我们可以完成想要做的事情的方法:
bool shouldReturnABC = true;
using (mocks.Record())
{
Expect.Call(s.GetSomething()).Repeat.Any();
LastCall.Do((Func<string>)delegate()
{
return shouldReturnABC ? "ABC" : "XYZ";
}
}
using (mocks.Playback())
{
DoStuff(s);
shouldReturnABC = false;
DoStuff(s);
}
乔治,
使用我们更新的代码,我可以正常工作:
MockRepository mocks = new MockRepository();
[Test]
public void Test()
{
IDateTimeFactory dtf = mocks.DynamicMock<IDateTimeFactory>();
DateTime desiredNowTime = DateTime.Now;
using (mocks.Record())
{
SetupResult.For(dtf.GetNow()).Do((Func<DateTime>)delegate { return desiredNowTime; });
}
using (mocks.Playback())
{
DoStuff(dtf); // Prints the current time
desiredNowTime += TimeSpan.FromMinutes(1); // 1 minute later
DoStuff(dtf); // Prints the time 1 minute from now
}
}
void DoStuff(IDateTimeFactory factory)
{
DateTime time = factory.GetNow();
Console.WriteLine(time);
}
FWIW,我不相信我们可以使用存根来完成此任务;我们需要改用模拟。

