9

I'm mocking some objects using Moq, and some of them can have fairly lengthy parameter-collection request objects passed in as arguments.

For ease of re-use and style, I'd like to be able to store these requests, with specific arguments, for use in the mocking setup. For example:

mockedObject
  .Setup(mo =>
    mo.GetBobbins(It.Is<GetBobbinsRequest>
      (r.Parameter1 == value1 && [...] & r.ParameterN == valueN))
  .Returns(someBobbins);

becomes:

var request = It.Is<GetBobbinsRequest>
  (r.Parameter1 == value1 && [...] & r.ParameterN == valueN);
mockedObject
  .Setup(mo => mo.GetBobbins(request))
  .Returns(someBobbins);

But that doesn't seem to work. I also tried:

Func<GetBobbinsRequest> request = () => It.Is<GetBobbinsRequest>
  (r.Parameter1 == value1 && [...] & r.ParameterN == valueN);
mockedObject
  .Setup(mo => mo.GetBobbins(request()))
  .Returns(someBobbins);

But no joy there either. Is there any way I can save an Itstyle object as a variable? Or am I missing some other obvious way of handling this?

2 Answers2

7

And... I've found the answer. It's Moq's Match (Class):

Creating a custom matcher is straightforward. You just need to create a method that returns a value from a call to Create with your matching condition and optional friendly render expression:

[Matcher]
public Order IsBigOrder()
{
    return Match<Order>.Create(
        o => o.GrandTotal >= 5000, 
        /* a friendly expression to render on failures */
        () => IsBigOrder());
}

This method can be used in any mock setup invocation:

mock.Setup(m => m.Submit(IsBigOrder()).Throws<UnauthorizedAccessException>();

http://www.nudoq.org/#!/Packages/Moq/Moq/Match(T)

7

A quick explanation as to why what you have in your question doesn't work, since I wrote it up before seeing your answer:

The call to It.Is actually ends up returning default(T) every time, so storing it and using it later would be the same as just passing null or whatever the default value of the parameter type is.

The reason why it has to be inline is because the call to It.Is actually works by setting a static member in a "mock context" that the call to Setup eventually gets around to using.

Patrick Quirk
  • 23,334
  • 2
  • 57
  • 88