In this fourth part of this series (which is a bit delayed due to my travels to MIX 09) I am going to discuss mocking multiple interfaces and doing callbacks in Moq 3. While these are not features that you are going to use very often, they are features that when you need them, it is often in situations where you have no other option.
Before we get to these two features, I want to really quickly touch on a previous feature that we have already looked at. On Twitter a little bit ago, there was a question about confirming that a method was not called on the mock. To check the number of calls:
mockFileWriter.Verify(fw => fw.WriteLine("1001,10.53"), Times.Exactly(1));
We can use the same construct to make sure that the method was never called:
mockFileWriter.Verify(fw => fw.WriteLine("1001,10.53"), Times.Never());
It is essentially the equivalent of saying “Times.Exactly(0)”, but it just looks much nicer, and provides a better error message. I just wanted to clear this up in case anyone else was wondering.
Mocking Multiple Interfaces
So now let’s look at mocking multiple interfaces. As we have already seen, if we want to create a mock of an interface then we can do it like this:
var mockFileWriter = new Mock<IFileWriter>();
But a situation that you can often get in is where a method requires a particular method, but then also expects the class to implement IDisposable. With some mocking frameworks this can be problematic. Thankfully Moq 3 provides us with an easy way to implement this by use of the “As” method on the mock itself. Some frameworks refer to this as a multi-mock:
var mockFileWriter = new Mock<IFileWriter>(); mockFileWriter.As<IDisposable>();
Now that our mock supports two interfaces, how do we create expectations and verifications on this mock? Well, in the call above, the “As” method returns a Mock<IDisposable"> which allows us to do setup and perform verification on it. We could either hold onto this mock, or if we wanted to later perform verification we could just call “As” again, since we can’t add an interface twice:
mockFileWriter.As<IDisposable>().Verify(d => d.Dispose());
Extremely powerful and very easy to work with!
Next we are going to look at callbacks, which are a feature in Moq that it is entirely possible that you’ll never use. They allow you to specify a chunk of code to be executed when a method is called. So, looking again at the “WriteLine” method above, we could record every invocation into a list:
var values = new List<string>(); mockFileWriter.Setup(fw => fw.WriteLine("1001,10.53")).Callback((string value) => values.Add(value));
Or we could ignore the parameter and just increment a count or something:
int count = 0; mockFileWriter.Setup(fw => fw.WriteLine("1001,10.53")).Callback(() => count++);
But since Moq provides functionality in both of these areas for most of what you would want to do, there isn’t really too many different points at which you would need these tools. In fact, if you think you need to use “Callback” you should probably look a little harder to see if Moq can do what you want to do automatically.
We looked at how to guarantee that a method is never called on a mock. Then we saw how to implement multiple interfaces on a single mock and finally how to use callbacks in Moq. I hope that you found this information useful, and hopefully the next entry in this series will be up soon. In that entry we are going to discuss raising exceptions and events from Mocks.