MatcherAttribute Class

Moq 2.6

Marks a method as a matcher, which allows complete replacement of the built-in It class with your own argument matching rules.

Namespace:  Moq
Assembly:  Moq (in Moq.dll) Version: 2.6.1014.1 (2.6.0.0)

Syntax

C#
public class MatcherAttribute : Attribute

Remarks

The argument matching is used to determine whether a concrete invocation in the mock matches a given expectation. This matching mechanism is fully extensible.

There are two parts of a matcher: the compiler matcher and the runtime matcher.

  • Compiler matcherUsed to satisfy the compiler requirements for the argument. Needs to be a method optionally receiving any arguments you might need for the matching, but with a return type that matches that of the argument.

    Let's say I want to match a lists of orders that contains a particular one. I might create a compiler matcher like the following:

    CopyC#
    public static class Orders
    {
      [Matcher]
      public static IEnumerable<Order> Contains(Order order)
      {
        return null;
      }
    }
    Now we can invoke this static method instead of an argument in an invocation:
    CopyC#
    var order = new Order { ... };
    var mock = new Mock<IRepository<Order>>();
    
    mock.Expect(x => x.Save(Orders.Contains(order)))
        .Throws<ArgumentException>();
    Note that the return value from the compiler matcher is irrelevant. This method will never be called, and is just used to satisfy the compiler and to signal Moq that this is not a method that we want to be invoked at runtime.
  • Runtime matcher The runtime matcher is the one that will actually perform evaluation when the test is run, and is defined by convention to have the same signature as the compiler matcher, but where the return value is the first argument to the call, which contains the object received by the actual invocation at runtime:
    CopyC#
    public static bool Contains(IEnumerable<Order> orders, Order order)
    {
      return orders.Contains(order);
    }
    At runtime, the mocked method will be invoked with a specific list of orders. This value will be passed to this runtime matcher as the first argument, while the second argument is the one specified in the expectation (x.Save(Orders.Contains(order))).

    The boolean returned determines whether the given argument has been matched. If all arguments to the expected method are matched, then the expectation is verified.

Using this extensible infrastructure, you can easily replace the entire It set of matchers with your own. You can also avoid the typical (and annoying) lengthy expressions that result when you have multiple arguments that use generics.

Examples

The following is the complete example explained above:
CopyC#
public static class Orders
{
  [Matcher]
  public static IEnumerable<Order> Contains(Order order)
  {
    return null;
  }

  public static bool Contains(IEnumerable<Order> orders, Order order)
  {
    return orders.Contains(order);
  }
}
And the concrete test using this matcher:
CopyC#
var order = new Order { ... };
var mock = new Mock<IRepository<Order>>();

mock.Expect(x => x.Save(Orders.Contains(order)))
    .Throws<ArgumentException>();

// use mock, invoke Save, and have the matcher filter.

Inheritance Hierarchy

Object
  Attribute
    Moq..::.MatcherAttribute

See Also