cusejuice
cusejuice

Reputation: 10671

Properly stubbing request/response with Sinon/Mocha

I'm relatively new to unit-testing on the backend and need some guidance as to how to unit-test the following. I'm using Mocha/Should/Sinon.

exports.get = function(req, res) {
   if (req.query.example) {
      return res.status(200).json({ success: true });
   } else {
      return res.status(400).json({error: true});
   } 
}

Upvotes: 6

Views: 6025

Answers (1)

Patrick Hund
Patrick Hund

Reputation: 20236

You can use Sinon's spy and stub functions to test your code like this:

const { spy, stub } = require('sinon');
const chai = require('chai');
chai.should();

describe('the get function', () => {
    let status,
        json,
        res;
    beforeEach(() => {
        status = stub();
        json = spy();
        res = { json, status };
        status.returns(res);
    });
    describe('if called with a request that has an example query', () => {
        beforeEach(() => get({ query: { example: true } }, res));
        it('calls status with code 200', () =>
            status.calledWith(200).should.be.ok
        );
        it('calls json with success: true', () =>
            json.calledWith({ success: true }).should.be.ok
        );
    });
    describe('if called with a request that doesn\'t have an example query', () => {
        beforeEach(() => get({ query: {} }, res));
        it('calls status with code 400', () =>
            status.calledWith(400).should.be.ok
        );
        it('calls json with error: true', () =>
            json.calledWith({ error: true }).should.be.ok
        );
    });
});

In the first beforeEach call, I'm creating a stub named status and a spy named json.

The status stub is used to test if the status method of the response is called with the correct response code.

The json spy is used to test if the json method of the response is called with the correct JSON code.

Note I'm using stub for status to be able to return the mock response from any call that goes to the status method, otherwise the chaining (res.status().json()) would not work.

For json it suffices to use a simple spy, because it is at the end of the chain.

Upvotes: 9

Related Questions