为什么没有Times.Always在Moq?

Pet*_*ery 6 c# unit-testing moq

使用Moq,可以验证是否永远不会使用某些参数(即满足某些谓词的参数)调用方法Times.Never.

但是如何验证,无论一个方法被调用多少次,它总是用某些参数调用?

默认似乎是Times.AtLeastOnce.

没有Times.Always.我错过了一些明显的东西吗 谢谢!

编辑:上周我向Moq邮件列表发布了一个建议,但看起来它还没有被审核.我会在这里发布任何更新.

编辑:一个例子.假设我正在测试一个生成XML文档的类.我想确保只生成有效的文档.换句话说,测试编写器依赖性被赋予有效的文档,具有有效的序列号,以进行编写.

should_only_write_valid_xml_documents

Mock.Get(this.writer).Verify(
    w => w.Write(
        It.Is<XDocument>(doc => XsdValidator.IsValid(doc)),
        It.Is<int>(n => n < 3)),
    Times.Always);
Run Code Online (Sandbox Code Playgroud)

doc*_*tan 8

多少次'总是?' Moq跟踪某些方法使用某些参数调用的所有时间,然后使用该数字与Times.Never,Times.AtLeastOnce等进行比较.

那么,如果一个方法被执行了4次并且你把它设置为'Times.Always'那么这甚至意味着什么?

Times.Never会检查以确保数字为零.

Times.AtLeastOnce将检查该数字是否大于或等于1.

时间.总是会检查数字是......?

您可以确定它应该以编程方式运行的次数,然后执行以下操作:

Times.Exactly(calculatedAmount)
Run Code Online (Sandbox Code Playgroud)

但是,Moq无法知道"永远"意味着什么.


Tru*_*ill 3

听起来您想要“严格”的模拟行为。如果使用预期参数以外的任何参数调用该方法,则测试将失败。

这可以在最小起订量中找到:

var mock = new Mock<IFoo>(MockBehavior.Strict);
Run Code Online (Sandbox Code Playgroud)

(示例取自Moq QuickStart。)

现在,模拟上的每个调用都必须有一个相应的Setup.

使用严格的模拟往往会导致脆弱的测试。我会避免这种技术,或者至少很少使用它。