Sinon Tips - makingsensetraining/mean-seed-blog GitHub Wiki

For using Unit Test, one of the tools that work together with mochaJS is SinonJS.

  • Sinon allows you to replace the difficult parts of your tests with something that makes testing simple.

  • Sinon helps eliminate complexity in tests by allowing you to easily create so called test-doubles.

  • Test-doubles are, like the name suggests, replacements for pieces of code used in your tests.

  • With Sinon, we can replace any JavaScript function with a test-double, which can then be configured to do a variety of things to make testing complex things simple.

  • Sinon splits test-doubles in 3 types:

  1. Spies
  2. Stubs
  3. Mocks

In the majority of cases I find useful to use stubs, when testing controllers or services. So with a stub, you may replace an specific function of the "lower layer" with some result you want.

There are 2 similar functions that are a bit confusing:

callsArgWith and callArgWith

The difference is that the first one callsArgWith you need to use it at the beginning of the test, before invoking it. And the 2nd one: callArgWith it need to be used after the call, so in the last part of the test.

Another important tip is that the first parameter of this function is the index of where the callback of the method we are replacing is. So if the function we are replacing is function(id, name, callback) the index is zero-based, so you have to call it with a 2 in the first parameter. And if you have some function without parameters, and only callback function(callback) you need to use 0 value.

For example:

describe('#show', function () {
    var findByIdStub;

    before(function () {
      findByIdStub = sinonSandbox.stub(UserModel, 'findById');
    });

    it('should find a user if it already exists', function (done) {

      findByIdStub.callsArgWith(1, null, {
        username: 'test01'
      });

      usersController.show({
        params: {
          userId: '#dummyId1234'
        }
      }, {
        send: function (response) {
          response.username.should.eql('test01');
          (response.profile === undefined).should.be.true;
          done();
        }
      });

    });
}

findByIdStub = sinonSandbox.stub(UserModel, 'findById'); In the above line we are replacing the findByIdfunction of the UserModel. So when called:

findByIdStub.callsArgWith(1, null, {
           username: 'test01'
});

As the findById method of the Model accepts 1 parameter and, later the callback we call with a 1 value as first parameter. and after that the callback values. First callback param is err, that's why we use null and the 2nd one is the response, so we fake the response of this method with a dummy object {username: 'test01'}

Useful links (with examples) are:

And of course the official documentation with the complete API: