Using your example, suppose you had an object - call it Foo
- that required a Shape
and Document
in the constructor. In this case, you would have two options:
- Build an actual
Document
and an actual Shape
, but using test data, and send these objects to the constructor during your test.
- Build a mock
Document
and a mock Shape
with just the functionality you need to be able to run your test actually implemented and send these to your constructor for your test.
If your objects are large and complex, then the first option can become prohibitive for testing, especially for larger projects where you might not know the inner workings of how the objects are supposed to be constructed or if they require certain parameters (like private keys, thumbprints, etc.) that you might not have access to. This really becomes a concern when you start to use dependency injection. So, to get around this, you interface out the objects you need to pass around and then you build mock implementations that allow you to test with them. Of course, that gets pretty repetitive after awhile, which is why Moq exists.
Returning to the example, you could test Foo
like so:
public void Foo_TestingFoo_DoesBar()
{
var mockDoc = new Mock<Document>();
var mockShape = new Mock<Shape>();
// "implement" the methods you will need during your test
mockDoc.Setup(...);
mockShape.Setup(...);
// Get the "actual" Document and Shape and use them as arguments to the ctor
var foo = new Foo(mockDoc.Object, mockShape.Object);
// Do stuff with foo
foo.DoBar();
// Verify that these objects were used how you expected them to be
mockDoc.Verify(...);
mockShape.Verify(...);
}