我正在尝试执行后续调用验证,我发现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。
答案 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()的自制解决方案(顺便说一句,它可以很好地包装) - 它会消除使用其他方式回调的能力,但是,我还没有使用它。
我发布这个答案,希望它有用。