订购方法使用Rhino-Mock存根返回值

我开始尝试使用Rhino-Mocks(3.6),同时阅读Roy Osherove的unit testing艺术 。 他有一个示例,演示了当使用相同的参数调用两次时,可以使用mocked方法编写脚本以返回不同的结果:

[Test] public void ReturnResultsFromMock() { MockRepository repository = new MockRepository(); IGetRestuls resultGetter = repository.DynamicMock(); using(repository.Record()) { resultGetter.GetSomeNumber("a"); LastCall.Return(1); resultGetter.GetSomeNumber("a"); LastCall.Return(2); resultGetter.GetSomeNumber("b"); LastCall.Return(3); } int result = resultGetter.GetSomeNumber("b"); Assert.AreEqual(3, result); int result2 = resultGetter.GetSomeNumber("a"); Assert.AreEqual(1, result2); int result3 = resultGetter.GetSomeNumber("a"); Assert.AreEqual(2, result3); } 

这很好用。 但是当我使用Stub和接受并返回字符串的方法尝试相同的事情时,我无法生成第二个返回值:

  [Test] public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived() { MockRepository mocks = new MockRepository(); IMessageProvider stub = mocks.Stub(); using (mocks.Record()) { stub.GetMessageForValue("a"); LastCall.Return("First call"); stub.GetMessageForValue("a"); LastCall.Return("Second call"); } Assert.AreEqual("First call", stub.GetMessageForValue("a")); Assert.AreEqual("Second call", stub.GetMessageForValue("a")); } } public interface IMessageProvider { string GetMessage(); string GetMessageForValue(string value); } 

此测试失败,因为两次呼叫都收到“First Call”。 我已经尝试了几种语法皱纹(使用mocks.Ordered(),SetResult,Expect等),但仍然无法获得第二个结果。

我做错了什么,或者这是Rhino-Mocks的限制? 我已经查看过这篇博文 ,但建议的语法并没有解决我的问题。

你缺少的是告诉存根,第一个值应该只返回一次:

 ... using (mocks.Record()) { stub.GetMessageForValue("a"); LastCall.Return("First call").Repeat.Once(); stub.GetMessageForValue("a"); LastCall.Return("Second call"); } 

当然,除非你对Repeat施加其他限制,否则你的“第二次通话”实际上意味着“第二次或后续通话”。

您可能还会考虑使用RhinoMocks现在提供的更新的Arrange,Act,Assert( AAA )语法:

 [Test] public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived() { IMessageProvider stub = MockRepository.GenerateStub(); stub.Expect(mp => mp.GetMessageForValue("a")) .Return("First call") .Repeat.Once(); stub.Expect(mp => mp.GetMessageForValue("a")) .Return("Second call"); Assert.AreEqual("First call", stub.GetMessageForValue("a")); Assert.AreEqual("Second call", stub.GetMessageForValue("a")); } 

它更简洁一些,通常可以使您不必担心存根的记录 – 回放 – 断言状态。 Derick Bailey写了一篇关于在Los Techies上使用Repeat的文章 。 它也碰巧使用AAA语法)。

我认为如果你正在使用存根,使用Expect并不合适,因为你不想要期望,而是替换你的依赖。

所以我相信如果你使用存根语法,它会更有意义:

 stub.Stub.(s=>s.GetMessageForValue("a")) .Return("First call").Repeat.Once(); stub.Stub.(s=>s.GetMessageForValue("a")) .Return("Second call").Repeat.Any;