我有一个我想要测试的逻辑,它使用依赖注入接口和一个(或多个)void方法,例如:
interface IMyService
{
void MethodA (MyComplexObject arg1, int arg2);
}
我想要的是为IMyService
创建一个存根,只需记录 MethodA
的方法调用,之后我就可以将其作为列表,如:
MyComplexObject actualParameter = serviceRecorder
.GetMethodRecordings("MethodA").GetRecord(10).GetInputParameter(0);
我需要这个来检查某个调用的这个参数的内容并对其进行断言。我知道还有其他的做法(比如设置带有约束的期望调用),但是当你有大量的调用并且你只想在第51个调用时,这似乎更容易编写,例如。
Rhino.Mocks中是否存在某种机制,或者我留给自己的设备(编写具有录制功能的虚拟IMyService
实现)?
注意:(我知道这可能导致测试变得脆弱,我知道后果)。
更新:这是我到目前为止所发现的(部分归功于Mark帮助将此模式命名为Test Spy):
答案 0 :(得分:5)
// arrange
var myServiceStub = MockRepository.GenerateStub<IMyService>();
var myComplexObj = new MyComplexObject
{
SomeProp = "something",
SomeOtherProp = "something else"
};
// act
myServiceStub.MethodA(myComplexObj, 10);
// assert
myServiceStub.AssertWasCalled(
x => x.MethodA(
Arg<MyComplexObject>.Matches(
arg1 => arg1.SomeProp == "something" &&
arg1.SomeOtherProp == "something else"
),
Arg<int>.Is.Equal(10)
)
);
备注:不要忘记将界面公开,否则Rhino Mocks将无法创建代理。
更新:
抱歉,我没有仔细阅读你的问题。以下是如何获得所需的行为:
var args = myServiceStub.GetArgumentsForCallsMadeOn(
x => x.MethodA(null, default(int)),
x => x.IgnoreArguments()
);
var theComplexObjectPassedAtThe51thCall = (MyComlexObject)args[50][0];
// TODO: assert something on this object
答案 1 :(得分:3)
查看Arrange-Act-Assert (AAA) syntax of Rhino Mocks。
总体而言,Record-Replay语法已过时。它发明时真是太棒了,但随着lambda表达式的出现,我们得到了更好的东西。
Rhino Mocks 4 is probably not going to support Record-Replay,而是依赖于lambda表达式,Moq也是如此。
最后,记录调用以供以后检查的测试双方称为测试间谍 - 有关详细信息,请参阅xUnit Test Patterns:)