Moq – Is it possible to specify in a Setup the Verify criteria (e.g. Times called)

installationmockingmoqtestingverify

If you need to Setup a return value, as well as Verify how many times the expression was called, can you do this in one statement?

From what I can gather, Moq's Setup(SomeExpression).Verifiable() called along with Verify(), basically does a Verify(SomeExpression, Times.AtLeastOnce)? i.e. it verifys the expression was called only.

Here's an example to explain the question better. For an interface:

interface IFoo
{
    int ReturnSomething();
}

Are the following two blocks equivalent (other than the first will Verify all setups marked as verifiable)?

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1).Verifiable();

    mock.Verify();
}

and

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1);

    mock.Verify((m) => m.ReturnSomething(), Times.AtLeastOnce());
}

If I wanted to verify the number of calls (say twice), is this the only way, where the expression is repeated for the Setup and Verify?

void Test()
{
    var mock = new Mock<IFoo>();
    mock.Setup((m) => m.ReturnSomething()).Returns(1);

    mock.Verify((m) => m.ReturnSomething(), Times.Exactly(2));
}

I just don't like having to call Setup and Verify. Well, since this is a good idea for AAA, to rephrase, I don't like having to repeat the expression for the Setup and Verify. At the moment I store the expression in a variable and pass it to each method, but doesn't feel so clean.

PS – The context for this is for a test checking when a cache is updated or not (expirations etc.)

Best Answer

I have this problem all the time. I use strict mocks, and I want to specify strictly (i.e. I used It.Is<>() instead of It.IsAny()) as well as verify strictly (i.e. specifying Times). You cannot use verifiable for this sadly, because Moq is missing a Verifiable(Times) overload.

The full expression of the call, including It.Is<>() is generally big. So in order to avoid duplication I generally resort to the following:

Expression<Action<MockedType>> expression = mockedTypeInstance => mockedTypeInstance.MockedMethod(It.Is<TFirstArgument>(firstArgument => <some complex statement>)/*, ...*/);
_mock.Setup(expression);

/* run the test*/

_mock.Verify(expression, Times.Once);

Not extremely readable, but I don't think there is another way to both use strict setup and strict verification.