For a general background on mocking, this answer does a pretty good job explaining it and why you might want to use it in your unit tests.
Specifically, Moq is a library that allows you to easily creates mock object and control their behavior. It's easiest to describe with examples, so let's look at your first code sample:
public interface IFoo {
public bool DoSomething(string);
public bool TryParse(string, out string));
}
/* 1 */ var mock = new Mock<IFoo>();
/* 2 */ mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
Line 1 creates a mock implementation of the IFoo
interface. Under the covers, Moq is using the Castle DynamicProxy library to create a concrete implementation of IFoo
on the fly, and then wrapping it in its own Mock
class so we can configure its behavior.
So now that we have a mock object, we'll frequently need to configure how it responds to having its methods invoked. That way, we can test how our system under test will react to it. The Setup
method on line 2 does exactly this, telling our mock object to return true
when DoSomething
is called with a parameter equal to "ping"
. Imagine you were using this mock to test a class like below:
public class TestObject
{
public string TestMethod(IFoo foo)
{
if (foo.DoSomething("ping"))
return "ping";
else if (foo.DoSomething("pong"))
return "pong";
return "blah";
}
}
To get complete test coverage, you'd want an implementation of IFoo
that can:
- return
true
for "ping"
in one test
- return
true
for "pong"
in another test
- return
false
for any argument in the last test
You could create your own mock object that has this behavior, e.g.:
public class MockFoo : IFoo
{
string trueValue;
public MockFoo(string trueValue)
{
this.trueValue = trueValue;
}
public bool DoSomething(string value)
{
return value == trueValue;
}
}
But that's kind of a pain when you have complicated logic, multiple parameters, or many dependencies; it just doesn't scale well. This is where mock objects and Moq can make things easy. The same setup in Moq for the three tests is:
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
mock.Setup(foo => foo.DoSomething("pong")).Returns(true);
mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(false);
In my opinion, that's simpler and more expressive about how you expect your IFoo
dependency to behave.
As for a guide, I think you'd be better off with a guide to mocking in general rather than a Moq-specific guide. Moq is just a library that makes using mock objects easier, and the Quickstart is a pretty good reference for the mechanics of using Moq. There are dozens of mocking tutorials and guides, just look for some. And remember, it didn't really "click" for me until I started using them. Find a coding kata and try mocking out for yourself!