codethinked (kōdthĭngked) adj. To be consumed by or obsessed with code.

Beginning Mocking With Moq 3 - Part 4

Other parts in this series

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!

Callbacks

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.

Summary

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.

Comments

pingback

Pingback from blog.oaoao.net

关于mop mock 有时间一定看完啊!!!!! | 我的奋斗

blog.oaoao.net

April 20. 2009 07:15

trackback

10 resources to learn Moq

10 resources to learn Moq

CodeClimber

October 23. 2009 09:55

trackback

MoQ(基于.net3.5,c#3.0的mock框架)简单介绍

我们在做单元测试的时候,常常困扰于数据的持久化问题,很多情况下我们不希望单元测试影响到数据库中的内容,而且受数据库的影响有时我们的单元测试的速度会很慢,所以我们往往希望将持久化部分隔离开,做单元测试的...

你听海是不是在笑

November 25. 2009 05:19

DaleB

When I run this test, count is not incremented in the debugger. What am I missing?

int count = 0;
mockFileWriter.Setup(fw => fw.WriteLine("1001,10.53")).Callback(() => count++);

DaleB

March 6. 2010 12:16

United States
Dan Doyon

I may start to sound like a broken record, but I'm missing the value in the mocking of multiple interfaces. Given your example with the filewriter how would you go about testing the IDisposable. Do you need to to make the IFileWriter extend IDisposable? A complete example would be much appreciated. Thanks!

Dan Doyon

April 13. 2010 12:14

United States

Add Comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading