SinonJs Mocks


This is part 5 of the automating testing series with Mocha, Chai and SinonJs. Part 1 and part 2 introduce the Mocha automated testing framework and the Chai assertion library. We then learned how to use SinonJs spies and stubs.

At the end of part 4, I promised that I would introduce a SinonJs feature that combines the advantages of spies and stubs with a twist, therefore we will continue exploring SinonJs with the introduction of mocks.

Mocking with SinonJs

SinonJs mocks observe behavior just like spies and replace behavior just like stubs. The added twist is that your expectations towards the mocked functionality are defined before using the observed method. A mock makes its test fail as soon as these expectations are violated.

Mocks are used for replacing and observing a tested piece of functionality. If you follow the principles of writing solid unit tests, you always test one piece of functionality in one test case. As a consequence, you will have at most one mocked object per test case. The rest of your objects can just be stubbed. If you think about mocking two objects in a single test case, most likely you will need at least two test cases.

Mocks only replace objects. Unlike spies, it does not make sense to talk about anonymous mocks, function mocks or method mocks.

Testers often use mocks for the purpose of verifying if an object interacts with its peers as expected, while the object under test stays completely isolated.

The mocking process works as follows:

As you can see in step 2, we formulate our expectations before exercising the tested piece of functionality. The formulated expectations are chainable.

Mock verification

The following example tests MarionetteJs code.

Notice that the serializeData method of a Marionette item view is supposed to call the toJSON method of its model. Verification passes without problems.

Let’s try to call the serializeData method more than once.

As soon as our expectation fails, a Javascript error is thrown, making our test case fail. This exception is thrown even without verifying our expectations. Why is the verify method useful then? The answer is that sometimes we expect all our previously specified conditions to be satisfied. For instance, if we expect the toJSON method to be called once while it has never been called, calling the verify method of the associated mock throws an error:

Mock Expectations

We will use Backbone Models to demonstrate the expressive power of mock expectations. For a full reference, visit the SinonJs documentation.

Summary

Use mocks to formulate your expectation on the object under test, then execute the tested action sequence, and verify if your expectations have been met. Mocks throw errors as soon as an expectation fails, implying that the test may fail before verification. Only use one mock per test. If you need to substitute other pieces of functionality with a simplified implementation, use stubs.

This was part six of the test automation series on Mocha, Chai, and SinonJs. If you are interested in reading more on test automation, check out the complete series by clicking here. The next episode is about fake timers in SinonJs.

Learn ES6 in Practice

Sign up below to access an ES6 course with many exercises and reference solutions.

  • Mocha, Chai, Sinon, ESLint and Proxyquire have been my go-to testing tools for modern JS projects for some time now. It’s nice to see an article series with this focus.

  • Thanks, Tracker1. I am happy writing about tools that help create better, more stable software. I just added another post you may like: http://www.zsoltnagy.eu/fake-timers-with-sinonjs/.