vendredi 4 décembre 2015

Unit testing using mocha, chai and mocks with sinon: what is going wrong with this?

I'm learning how to unit test in Express with Mocha, Chai expect assertions, and Sinon spies etc. I have two tests, one of which passes and one of which fails, and I cannot work out what is the relevant difference between the two situations. Here's the test code:

var chai = require('chai');
var expect = chai.expect;
var sinon = require('sinon');

var getLogin = require('../routes/login/getLogin');
var postLogin = require('../routes/login/postLogin');

describe('Login routes: ', function() {
  var req, res;

  beforeEach(function() {
    // The functions being tested won't use any methods not listed here
    req = {};
    res = {
      render: function(templateName) {},
      json: function(obj) {},
      status: function(responseStatus) {
        return this;
      },
      sendStatus: function(responseStatus) {}
    };
  });

  describe('GET /login', function() {

    it('should render the login template.', function() {
      var spy = sinon.spy(res, 'render');
      getLogin(req, res);

      expect(spy.callCount).to.equal(1);
      expect(spy.calledWith('login')).to.equal(true);
    });

  });

  describe('POST /login', function() {

    describe('with a valid email and password', function() {
      var credentials = {email: 'test@email.com', password: 'testing123'};

      it('should respond with a 200 status code.', function() {
        var spy = sinon.spy(res, 'sendStatus');
        req.body = credentials;

        postLogin(req, res);

        expect(spy.callCount).to.equal(1);
        expect(spy.calledWith(200)).to.equal(true);
      });
    });

  });

});

The first test passes for the GET module, code here:

var getLogin = function(req, res) {
  res.render('login');
};

module.exports = getLogin;

But the second test fails, with an AssertionError saying spy.callCount equals 0, not 1. Code for the POST module here:

var fs = require('fs');
var path = require('path');

var PASSWORDS_FILE = path.join(__dirname, '../../passwords.json');

var postLogin = function(req, res) {
  var params = req.body;
  var email = params.email;
  var password = params.password;

  fs.readFile(PASSWORDS_FILE, function(err, data) {
    if (err) {
      console.error(err);
      process.exit(1);
    }

    var passwords = JSON.parse(data);
    if (!passwords.hasOwnProperty(email)) {
      res.status(401).json({error: 'Email not found.'});
    } else if (passwords[email] !== password) {
      res.status(401).json({error: 'Incorrect password.'});
    } else {
      console.log("About to sendStatus(200)");
      res.sendStatus(200);
      console.log("Just did sendStatus(200)");
    }

  });

};

module.exports = postLogin;

The POST module is more complex than the GET one, but I can't work out what the relevant difference is as the structure of the tests is exactly the same and those two console.logs around the call to res.sendStatus(200) both appear in the output.

What am I doing wrong?

Aucun commentaire:

Enregistrer un commentaire