http://blogs.clariusconsulting.net/kzu

Daniel Cazzulino's Blog

Go Back to
kzu′s Latest post

New Moq features for mock verification and creation

I wrote before about What’s wrong with the Record/Reply/Verify model for mocking frameworks, and in that context, why Moq didn’t provide a mock verification functionality.

Given that the project is driven by users’ feedback, both internal (our own team who’s using it extensively) and external, we added mock verification to Moq. I guess this finally settles the issue of whether it’s a mocking framework or a stub framework :) .

Verification

So let’s review how this feature is used and a couple alternatives that are in place:

//setup - data
var order = new Order(TALISKER, 50);
var mock = new Mock<IWarehouse>(MockBehavior.Relaxed);

//setup - expectations
mock.Expect(x => x.HasInventory(TALISKER, 50)).Returns(true);
...
// other test code, exercising the mock
...
//verify state
Assert.IsTrue(order.IsFilled);
//verify interaction
mock.VerifyAll();

The  new VerifyAll() method will ensure all expectations are satisfied (invoked). There’s also a Verify() alternative which is more flexible, allowing you to verify only those expectations that have been marked as Verifiable:

//setup - expectations
mock.Expect(x => x.HasInventory(TALISKER, 50)).Verifiable().Returns(true);//setup other expectation that may not be Verifiable
...
//verify only Verifiable expectations.
mock.Verify();

This alternative is especially useful when you’re setting up optional default expectations in a fixture setup and verifying at tear down:

Mock<IWarehouse> warehouseMock;

[SetUp]
public void SetUp()
{
    warehouseMock = new Mock<IWarehouse>(MockBehavior.Loose);

    // setup default non-verifiable (optional) expectation/return value
    warehouseMock.Expect(warehouse => warehouse.HasInventory(TALISKER, 50)).Returns(true);
}

[TearDown]
public void TearDown()
{
    warehouseMock.Verify();
}

Reusing default expectations in fixture setups makes for much more compact and targeted mock setups in specific tests. All the boring default (maybe optional) interactions are moved away to the setup. In my experience (and that of some of our users) this makes for much cleaner tests.

This can also be combined with the ability to override expectations. So in the example above, if a particular test needs to return a different value, it can just re-set the expectation and the new expectation will be the active one:

// override default expectation set in fixture setup
warehouseMock.Expect(warehouse => warehouse.HasInventory(TALISKER, 50)).Returns(false);

Consistency via MockFactory

After some very good feedback and a bit of back-and-forth with Garry over at Hanselforum, we finally settled on a way to make mock creation and verification easier when multiple mocks are in use in a single test.

If you’re using a mock behavior other than the default (i.e. you want strict mocks that will throw for anything without an explicit expectation, or the absolute opposite, a loose mock) you’ll be passing this enumeration value to each and every mock you create:

//setup - data
var warehouseMock = new Mock<IWarehouse>(MockBehavior.Loose);var loggerMock = new Mock<ILogger>(MockBehavior.Loose);//other mocks with same behavior 

If your mocks always have the same behavior, and you use a particular style of verification always (Verify or VerifyAll as explained above), you can save some boring typing and gain consistency by using a MockFactory. This factory can be initialized at fixture setup and used on tear down to verify all mocks created using its Create method:

MockFactory factory;

[SetUp]
public void SetUp()
{
    factory = new MockFactory(MockBehavior.Loose);
}

[TearDown]
public void TearDown()
{
    factory.Verify();
}

[Test]
public void ShouldDoSomething()
{
    //...
    var mock = factory.Create<IWarehouse>();
    //...
    // all created mocks will be verified automatically
    // when the test finishes
}

This feature further reduces code duplication and makes tests even more concise. The explicit nature of expectations and verification makes it unnecessary to (ab)use the disposable pattern which precludes fixture setup/teardown reuse.

 

We continue to strive to keep Moq faithful to its core design principle of simplicity by allowing manipulation of mock instances directly. Most mocking newcomers to will find this a refreshing alternative to the established and somewhat unnatural (I’d say also artificial) record/reply model.

Let us know what you’d like to see in future versions, what you like and what you don’t! You can either submit an issue (not only bugs, but also suggestions) or send an email to the user’s group.

Comments