Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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});
   } 
}
like image 939
cusejuice Avatar asked May 02 '17 13:05

cusejuice


1 Answers

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.

like image 130
Patrick Hund Avatar answered Nov 01 '22 01:11

Patrick Hund