Dan*_*vay 9 c# unit-testing rhino-mocks
我开始尝试使用Rhino-Mocks(3.6),同时阅读Roy Osherove的单元测试艺术.他有一个示例,演示了当使用相同的参数调用两次时,可以编写一个mocked方法来返回不同的结果:
[Test]
public void ReturnResultsFromMock()
{
MockRepository repository = new MockRepository();
IGetRestuls resultGetter = repository.DynamicMock<IGetRestuls>();
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);
}
Run Code Online (Sandbox Code Playgroud)
这很好用.但是当我使用Stub尝试同样的事情,以及接受并返回字符串的方法时,我无法生成第二个返回值:
[Test]
public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived()
{
MockRepository mocks = new MockRepository();
IMessageProvider stub = mocks.Stub<IMessageProvider>();
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);
}
Run Code Online (Sandbox Code Playgroud)
此测试失败,因为两次呼叫都收到"First Call".我已经尝试了几种语法皱纹(使用mocks.Ordered(),SetResult,Expect等),但仍然无法获得第二个结果.
我做错了什么,或者这是Rhino-Mocks的限制?我已经查看过这篇博文,但建议的语法并没有解决我的问题.
Mr.*_*tty 10
你缺少的是告诉存根,第一个值应该只返回一次:
...
using (mocks.Record())
{
stub.GetMessageForValue("a");
LastCall.Return("First call").Repeat.Once();
stub.GetMessageForValue("a");
LastCall.Return("Second call");
}
Run Code Online (Sandbox Code Playgroud)
当然,除非你对Repeat施加其他限制,否则你的"第二次通话"实际上意味着"第二次或后续通话".
你也可以考虑使用RhinoMocks现在提供的更新的Arrange,Act,Assert(AAA)语法:
[Test]
public void StubMethodWithStringParameter_ScriptTwoResponses_SameResponseReceived()
{
IMessageProvider stub = MockRepository.GenerateStub<IMessageProvider>();
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"));
}
Run Code Online (Sandbox Code Playgroud)
它更简洁一些,通常可以使您不必担心存根的记录 - 回放 - 断言状态.Derick Bailey写了一篇关于在Los Techies上使用Repeat的文章.它也碰巧使用AAA语法).