Reset mock verification in Moq?
Solution 1:
This is now supported in Moq
Use .Invocations.Clear()
on the latest version of the library:
var foo = new Mock<foo>();
foo.Invocations.Clear();
Old answer
I think long after this post was created they added the functionality that the OP had asked for, there is a Moq extension method called Moq.MockExtensions.ResetCalls().
With this method you can do exactly what you wished as shown below:
[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());
foo.ResetCalls(); // *** Reset the verification here with this glorious method ***
objectUnderTest.DoStuffToPushIntoState2(); // more lines of code
foo.Verify(x => x.Fizz(), Times.Never());
}
Solution 2:
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());
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.
Edit
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");
}
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.
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.