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,我不相信我们可以使用存根来完成此任务;我们需要改用模拟。