C# 为什么不是';没有时间了。总是在Moq吗?
使用Moq,可以使用C# 为什么不是';没有时间了。总是在Moq吗?,c#,unit-testing,moq,C#,Unit Testing,Moq,使用Moq,可以使用次数验证方法是否使用某些参数(即满足某些谓词的参数)调用从不 但是,如何验证,无论一个方法被调用多少次,它总是使用某些参数被调用 默认值为次。至少一次 没有时间。始终。我错过了什么明显的东西吗?谢谢 编辑:我上周在Moq邮件列表上发布了一条建议,但看起来还没有被修改。我会在这里发布任何更新 编辑:一个例子。假设我正在测试一个生成XML文档的类。我想确保只生成有效的文档。换句话说,测试writer依赖项是否只有一个有效的文档和一个有效的序列号才能写入 should_only_w
次数验证方法是否使用某些参数(即满足某些谓词的参数)调用从不
但是,如何验证,无论一个方法被调用多少次,它总是使用某些参数被调用
默认值为次。至少一次
没有时间。始终。我错过了什么明显的东西吗?谢谢
编辑:我上周在Moq邮件列表上发布了一条建议,但看起来还没有被修改。我会在这里发布任何更新
编辑:一个例子。假设我正在测试一个生成XML文档的类。我想确保只生成有效的文档。换句话说,测试writer依赖项是否只有一个有效的文档和一个有效的序列号才能写入
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);
应该只写有效的xml文档吗
Mock.Get(this.writer).验证(
w=>w.写入(
It.Is(doc=>XsdValidator.IsValid(doc)),
它是(n=>n<3)),
时代,永远);
那么“始终”有多少次?Moq会记录使用某些参数调用某个方法的所有时间,然后使用该数字与times.Never、times.atleastone等进行比较
所以,如果一个方法执行了4次,并且你将它设置为“times.Always”,这意味着什么
时间。永远不会检查以确保数字为零
Times.AtLeastOnce将检查该数字是否大于或等于1
时间。总是会检查号码是否为
您可以确定它应该以编程方式运行的次数,然后执行以下操作:
Times.Exactly(calculatedAmount)
但是Moq无法知道“始终”是什么意思。我的建议是为方法创建一个“后备”匹配。i任何条件。然后,您可以验证时间。永远不要对该匹配进行验证,因为该匹配应始终被更具体的匹配所取代。听起来您需要“严格”的模拟行为。如果使用预期参数以外的任何参数调用该方法,则测试将失败
这在最低起订量中提供:
var mock = new Mock<IFoo>(MockBehavior.Strict);
var mock=new mock(MockBehavior.Strict);
(示例摘自。)
模拟上的每个调用现在都必须有相应的设置
使用严格的模拟往往会导致脆性测试。我会避免使用这种技术,或者至少少用它。您可以应用逻辑反转来始终验证
例如:
假设您要执行以下验证:
mock.Verify(x => x.Method(It.Is<int>(i => i == 10)), Times.Always());
mock.Verify(x=>x.Method(It.Is(i=>i==10)),Times.Always();
您只需将其替换为:
mock.Verify(x => x.Method(It.Is<int>(i => i != 10)), Times.Never());
mock.Verify(x=>x.Method(It.Is(i=>i!=10)),Times.Never();
“始终”意味着知道“始终”是多少次,如果你知道,为什么不使用时间(n)来代替呢?不,它不是-这就是问题的关键所在。想象一个方法在一个大小是动态确定的循环中被调用,然后在循环迭代中我会检查这个方法被调用了一次又一次。这是假设循环在测试代码中。如果它在要测试的代码中,那么我会重新设计可测试性,这样我就可以钩住循环代码来检查每个方法调用。我看不出这怎么可能是真的。莫克知道“从不”的意思——“总是”是“从不”的反义词。您提到的数字只会与调用总数进行比较,而不是零。@PeteMontgomery Moq知道“从不”的含义,因为它表示零。“始终”是一个不明确的数字,可以包括任何正整数。希望Moq测试每次调用一个方法时,它是否被调用,这似乎是一个没有实际意义的问题。如果要执行多次(比如在循环中),只需保留一个表示应该调用它多少次的变量,并运行一个测试,该测试在次上进行测试。确切地说(numTimesShouldRun)。嗯,恐怕我认为这是自相矛盾的,或者误解了问题的重点。我说的是测试每次调用方法时,都会使用某些参数调用它。看看其他答案。@PeteMontgomery考虑到目前的行为,偶尔来看看可能会让人困惑。总是这样。“Verify”方法声明“验证是否在模拟上执行了与给定表达式匹配的特定调用。”添加Times.Always值将从根本上更改Verify方法的操作。对于每一个其他值,它都是正常的,但对于次,它现在总是检查它是否没有使用其他参数调用该方法。如果你在严格意义上使用Verify,“总是”将是一个模棱两可的术语(如我在回答中所解释的),因此没有意义。胡说,你可以对Times说完全相同的话。从来没有。你能演示如何做到这一点吗?(如果这是您的意思,那么验证调用不会“失败”——据我所知,它们是独立的。)或者您的意思是重写测试以使用使用时间。永远不会?有时这是不可能的,因为您必须指定所有可能的无效参数。干杯,皮特。当然可以。但是如果它存在的话,这个选项可以让我避免切换到严格的模拟和它所需要的额外设置的痛苦。嗨,我的问题的确切动机是,尽管你可以在简单的情况下这样做,比如你的例子,但你不能在所有情况下都这样做。例如:验证只使用满足特定条件的XML文档调用方法。您无法编写所有可能不满足这些条件的XML文档,因此您无法“反转”验证以使用时间。从不。抱歉,我在最后一点上完全错了-我刚刚意识到您通常可以反转和使用时间。从不-前提是您一次只测试一个参数。