我试图执行后续调用验证,我发现moq支持InSequence()方法,如:
MockSequence s = new MockSequence();
validator.InSequence(s).Setup(m => m.IsValid(It.IsAny<Frame>())).Returns(true);
encryptor.InSequence(s).Setup(m=>m.Encrypt(It.IsAny<Frame>()));
socket.InSequence(s).Setup(m => m.Send(It.IsAny<Frame>()));
compressor.InSequence(s).Setup(m => m.Compress(It.IsAny<Frame>()));
Run Code Online (Sandbox Code Playgroud)
但是,这似乎仅在我将模拟行为指定为"严格"时才起作用,这禁止我在模拟对象上调用其他方法.但是,我希望能够在这些对象上调用其他方法,我只是希望这些调用按顺序执行.
是否有任何"支持"的方式(而不是诉诸.Callback()和手工实现)?我找到了一个名为moq.sequence的附加库,但是,预编译版本不适用于最新的Moq.
好吧,我通过在SVN浏览器中挖掘Moq的源代码来调查这个案例(仅用于记录 - 所讨论的moq版本是Moq.4.0.10827.Final).
我的调查导致我:http: //code.google.com/p/moq/source/browse/trunk/Source/MockSequence.cs?spec = snn751&r = 712
通过查看InSequence()方法,我现在可以看到整个实现基于When() 方法.
所以,实际上,以下代码:
validator.InSequence(s).Setup(m => m.IsValid(It.IsAny<Frame>())).Returns(true);
Run Code Online (Sandbox Code Playgroud)
结束如下:
validator.When(/* call is made in sequence */).Setup(m => m.IsValid(It.IsAny<Frame>())).Returns(true);
Run Code Online (Sandbox Code Playgroud)
换句话说,这只是设置条件行为 - 当按顺序调用方法时,指定的Setup()将起作用.否则,执行默认实现.并且因为对于严格的模拟,默认实现是抛出异常(调用被视为未指定),整个解决方案都有效.
因此,似乎当前解决方案与松散的模拟工作将是非常麻烦的.我将坚持使用基于Callback()的自制解决方案(顺便说一句,它可以很好地包装) - 它会消除使用其他方式回调的能力,但是,我还没有使用它.
我发布这个答案希望它有用.