我可以使用moq的InSequence()和MockBehavior.Loose吗?

时间:2012-02-07 08:03:45

标签: c# mocking moq

我正在尝试执行后续调用验证,我发现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>()));

然而,这似乎只有在我将模拟行为指定为“strict”时才有效,这禁止我在模拟对象上调用其他方法。但是,我希望能够在这些对象上调用其他方法,我只是希望这些调用按顺序执行。

是否有任何“支持”方式(而不是诉诸.Callback()和手工实现)?我找到了一个名为moq.sequence的附加库,但是,预编译版本不适用于最新的Moq。

1 个答案:

答案 0 :(得分:9)

好的,我自己通过在SVN浏览器中挖掘Moq的源代码来调查此案例(仅用于记录 - 所讨论的moq版本是 Moq.4.0.10827.Final )。

我的调查让我: http://code.google.com/p/moq/source/browse/trunk/Source/MockSequence.cs?spec=svn751&r=712

通过查看InSequence()方法,我现在可以看到整个实现基于When()方法。

所以,实际上,以下代码:

validator.InSequence(s).Setup(m => m.IsValid(It.IsAny<Frame>())).Returns(true);

最终会像:

validator.When(/* call is made in sequence */).Setup(m => m.IsValid(It.IsAny<Frame>())).Returns(true);

换句话说,这只是设置条件行为 - 当按顺序调用方法时,指定的Setup()将起作用。否则,执行默认实现。并且因为对于严格的模拟,默认实现是抛出异常(调用被视为未指定),整个解决方案都有效。

因此,似乎目前使用松散模拟工作的解决方案将非常麻烦。我将坚持使用基于Callback()的自制解决方案(顺便说一句,它可以很好地包装) - 它会消除使用其他方式回调的能力,但是,我还没有使用它。

我发布这个答案,希望它有用。