52

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.)

Giulio Caccin
  • 2,962
  • 6
  • 36
  • 57
GregS
  • 681
  • 1
  • 6
  • 8
  • This is using Moq 4 (I have seen old code snippets where there are methods on the ISetup such as AtMostOnce) – GregS Mar 12 '13 at 12:05

5 Answers5

28

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.

Evren Kuzucuoglu
  • 3,781
  • 28
  • 51
17

To answer the first question, yes the two blocks are equivalent. Both will fail when .Verify is called if the method on the mock wasn't called.

You can't specify the verify up front as far as I am aware and if you think about it, it makes sense.

This is specifying the behavior of the mock:

mock.Setup(m => m.ReturnSomething()).Returns(1);

This is verifying the behavior of the caller:

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

Personally I prefer calling verify individually to confirm the required behavior of the caller, the .Verifiable() and .Verify() are shortcuts that are less strict (they just check the method was called one or more times) however if you know your code should only call a method once, put the verify in at the end to confirm it.

I started doing that after a code merge resulted in a method being called twice, the test still passed since it was called at least once but it also meant that something else happened multiple times which shouldn't have!

Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
  • 10
    That is unfortunate, considering Rhino Mocks supports setup and verify in a single statement. I'd think this would be one of the most common use-cases (if not _the_ most common), so I'm baffled how this is not included in the framework, even now, over three years later. Guess I'll switch to Rhino Mocks... – BlueRaja - Danny Pflughoeft Sep 02 '16 at 05:06
9

Expounding on the answer by Evren Kuzucuoglu, I created the following extension methods to make creating the expressions a little simpler:

/// <summary>
/// Creates a method call expression that can be passed to both <see cref="Setup"/> and <see cref="Verify"/>.
/// </summary>
/// <typeparam name="T">Mocked object type.</typeparam>
/// <param name="mock">Mock of <see cref="T"/>.</param>
/// <param name="expression">Method call expression to record.</param>
/// <returns>Method call expression.</returns>
public static Expression<Action<T>> CallTo<T>(this Mock<T> mock, Expression<Action<T>> expression) where T : class
{
    return expression;
}

/// <summary>
/// Creates a method call expression that can be passed to both <see cref="Setup"/> and <see cref="Verify"/>.
/// </summary>
/// <typeparam name="T">Mocked object type.</typeparam>
/// <typeparam name="TResult">Method call return type.</typeparam>
/// <param name="mock">Mock of <see cref="T"/>.</param>
/// <param name="expression">Method call expression to record.</param>
/// <returns>Method call expression.</returns>
public static Expression<Func<T, TResult>> CallTo<T, TResult>(this Mock<T> mock, Expression<Func<T, TResult>> expression) where T : class
{
    return expression;
}

Usage example:

var createMapperCall = mockMappingFactory.CallTo(x => x.CreateMapper());
mockMappingFactory.Setup(createMapperCall).Returns(mockMapper.Object);

mockMappingFactory.Verify(createMapperCall, Times.Once());
Jack A.
  • 4,245
  • 1
  • 20
  • 34
3

I created a utility class that takes care of this:

public class TestUtils
{
  private static List<Action> verifyActions = new List<Action>();

  public static void InitVerifyActions() => verifyActions = new List<Action>();

  public static void VerifyAllSetups()
  {
    foreach (var action in verifyActions)
    {
      action.Invoke();
    }
  }

  public static ISetup<T> SetupAndVerify<T>(Mock<T> mock, Expression<Action<T>> expression, Times times) where T : class
  {
    verifyActions.Add(() => mock.Verify(expression, times));
    return mock.Setup(expression);
  }

  public static ISetup<T, TResult> SetupAndVerify<T, TResult>(Mock<T> mock, Expression<Func<T, TResult>> expression, Times times) where T : class
  {
    verifyActions.Add(() => mock.Verify(expression, times));
    return mock.Setup(expression);
  }
}

Then in TestInitialize(), I call TestUtils.InitVerifyActions(), and in the unit tests:

TestUtils.SetupAndVerify(myMock, m => m.Foo("bar"), Times.Once()).Returns("baz");
TestUtils.SetupAndVerify(myOtherMock, m => m.Blah(), Times.Once());
...
TestUtils.VerifyAllSetups();
DSoa
  • 663
  • 8
  • 19
0

While far from enough Moq indeed has the AtMost() and AtMostOnce() methods on the Setup call, however it is marked as Obsolete, but it appears to be a mistake according to this GitHub issue

yoel halb
  • 12,188
  • 3
  • 57
  • 52