Properly stubbing request/response with Sinon/Mocha

javascript, mocha.js, node.js, sinon, unit-testing

Solution

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.

Problem

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}); } } ```

Original source