重置Moq中的模拟验证? [英] Reset mock verification in Moq?
问题描述
如此设置:
public interface IFoo
{
void Fizz();
}
[Test]
public void A()
{
var foo = new Mock<IFoo>(MockBehavior.Loose);
foo.Object.Fizz();
foo.Verify(x => x.Fizz());
// stuff here
foo.Verify(x => x.Fizz(), Times.Never()); // currently this fails
}
基本上,我想在// stuff here
处输入一些代码以使foo.Verify(x => x.Fizz(), Times.Never())
通过.
Basically I'd like to enter some code at the // stuff here
to make the foo.Verify(x => x.Fizz(), Times.Never())
pass.
由于这很可能构成了最小的起订量/单元测试滥用,所以我的理由是我可以执行以下操作:
And because this probably constitutes moq/unit testing abuse, my justification is so I can do something like this:
[Test]
public void Justification()
{
var foo = new Mock<IFoo>(MockBehavior.Loose);
foo.Setup(x => x.Fizz());
var objectUnderTest = new ObjectUnderTest(foo.Object);
objectUnderTest.DoStuffToPushIntoState1(); // this is various lines of code and setup
foo.Verify(x => x.Fizz());
// reset the verification here
objectUnderTest.DoStuffToPushIntoState2(); // more lines of code
foo.Verify(x => x.Fizz(), Times.Never());
}
基本上,我有一个状态对象,需要大量工作(包括制作各种模拟对象和其他操作)将其推入State1.然后,我想测试从State1到State2的过渡.与其复制或抽象代码,我不希望仅重复使用State1测试,而是将其推送到State2并执行我的断言-除了验证调用之外,我可以做所有这些事情.
Basically, I have a state object where a fair bit of work (both in terms of making various mock objects and other faffing around) is requires to push it into State1. Then I want to test the transition from State1 to State2. Instead of duplicating or abstracting the code I'd prefer to just re-use the State1 test, push it into State2 and perform my Asserts - all of which I can do except the verification calls.
推荐答案
我认为您无法重置这样的模拟.相反,如果您知道在转换到状态1时应调用Fizz
一次,则可以像这样进行验证:
I don't think you can reset a mock like this. Instead, if you know that Fizz
should be called once when transitioning to state 1, you can do your verifies like this:
objectUnderTest.DoStuffToPushIntoState1();
foo.Verify(x => x.Fizz(), Times.Once()); // or however many times you expect it to be called
objectUnderTest.DoStuffToPushIntoState2();
foo.Verify(x => x.Fizz(), Times.Once());
话虽如此,我仍将为此创建两个单独的测试.作为两个测试,可以更轻松地查看到状态1的转换是否失败,或者到状态2的转换是否失败.此外,当像这样一起测试时,如果您向状态1的转换失败,则测试方法会退出,并且您不会转换至状态2.
Having said that, I would still create two separate tests for this. As two tests, it's easier to see whether the transition into state 1 is failing, or the transition into state 2 is failing. Additionally, when tested together like this, if your transition into state 1 fails, the test method exits and your transition into state 2 doesn't get tested.
编辑
作为示例,我使用xUnit测试了以下代码:
As an example of this, I tested the following code with xUnit:
[Fact]
public void Test()
{
var foo = new Mock<IFoo>(MockBehavior.Loose);
foo.Object.Fizz();
foo.Verify(x => x.Fizz(), Times.Once(), "Failed After State 1");
// stuff here
foo.Object.Fizz();
foo.Verify(x => x.Fizz(), Times.Once(), "Failed after State 2");
}
该测试失败,并显示消息状态2之后失败".这模拟了如果将foo推入状态2的方法调用Fizz
会发生的情况.如果是这样,第二个Verify
将失败.
This test fails with the message, "Failed after State 2". This simulates what would happen if your method that pushes foo into State 2 calls Fizz
. If it does, the second Verify
will fail.
再次查看您的代码,因为您正在调用一个方法来验证它是否在模拟对象上调用了/不调用了另一方法,所以我认为您需要将CallBase
设置为true
,以便将基本DoStuffToPushIntoState2
设置为而不是模拟的覆盖.
Looking at your code again, since you are calling one method to verify it does/does not call another method on the mock, I think you need to set CallBase
to true
so that the base DoStuffToPushIntoState2
is called rather than the mock's override.
这篇关于重置Moq中的模拟验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!