为什么不是';没有时代,永远在Moq

本文关键字:时代 永远 Moq 为什么不 | 更新日期: 2023-09-27 18:20:46

使用Moq,可以验证是否使用Times.Never使用某些参数(即满足某些谓词的参数)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);

为什么不是';没有时代,永远在Moq

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

那么,如果一个方法被执行了4次,并且你将其设置为"times.Always",这意味着什么?

次数。永远不会检查以确保数字为零。

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

时代。总是会检查号码是?

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

Times.Exactly(calculatedAmount)

但莫无法知道"永远"是什么意思。

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

这在Moq:中可用

var mock = new Mock<IFoo>(MockBehavior.Strict);

(示例取自Moq QuickStart。)

mock上的每个调用现在都必须有一个相应的Setup

使用严格的mock往往会导致脆弱的测试。我会避免这种技巧,或者至少要少用。

您可以应用逻辑反转来验证ALWAYS。

例如:

假设您想进行以下验证:

mock.Verify(x => x.Method(It.Is<int>(i => i == 10)), Times.Always());

您可以简单地将其替换为:

mock.Verify(x => x.Method(It.Is<int>(i => i != 10)), Times.Never());

我的建议是为具有It.IsAny条件的方法创建一个"回退"匹配。然后你可以验证Times.Never,它应该总是被更具体的匹配所取代。