Arpit Kumar
Arpit Kumar

Reputation: 2249

how to use sinon js with Express js unit testing

Hi i want to do unit testing on my express js code i want to mock data so after searching multiple websites and blogs i found this library but i am not clear how can i use this library for mocking or data. My testing code is

var request = require('supertest');
var server = require('./app');
var chai = require('chai');
var chaiHttp = require('chai-http');

var server = require('./app');

var should = chai.should();
chai.use(chaiHttp);

describe('loading express', function () {

  it('responds to /', function testSlash(done) {
    request(server)
      .get('/')
      .expect(200, done);
  });

  it('404 everything else', function testPath(done) {
    request(server)
      .get('/foo/bar')
      .expect(404, done);
  });

  it('responds to /customers/getCustomerData', function testPath(done) {
    request(server)
      .get('/customers/getCustomerData?id=0987654321')
      .end(function(err, res){
        res.should.have.status(200);
        res.body.should.be.a('object');
        res.body.status.should.equal("success");
        res.body.data.customerId.should.equal("0987654321");

        done();
      });
  });

});

Currently this code is fetching data from database but i want Unit testing using mock data. How can i achieve this?

__EDIT__

I want to test the code which is written inside Express js routes file. this routes i am calling inside app.js file like this

var customers = require('./routes/customers');
app.use('/customers', customers);

now the code which customers route file contain is

function getCustomerData(req, res, next) {
    var response = {};
    var cb = function (response) {
        res.send(response);
    }
    var modelObj = req.models.customer_master;
    var data = req.query;
    controllers.customers.get(modelObj, data, cb);
};
router.get('/getCustomerData', function (req, res, next) {
    getCustomerData(req, res, next);
});

I want to test the response of "get" method using mock data

Upvotes: 5

Views: 8815

Answers (3)

starshine wang
starshine wang

Reputation: 636

Additionaly, if you write many test files, the stub may not work because of cache. I have to clear cache before initializing the stub and the server. The order is also important.

// have to clear every module which belongs to the require chain
// APP require FOO ROUTE require FOO CONTROLLER require BAR LIB
const caches = [
    '../app',
    '../routes/foo',
    '../controller/foo',
];
caches.forEach(cache => {
    delete require.cache[require.resolve(cache)];
});
// mock
const bar = require('../lib/bar');
sinon.stub(bar, 'bar').callsFake(async function() {
    return null;
});
app = require('../app');

// ... then the test ...

I found this thread helpful.

Upvotes: 0

user2347763
user2347763

Reputation: 489

If you wish to mock, you can use sinon express mocks here or if you want to test the actual response data, JSON, use this example

The express route, in the example, takes a parameter and returns a JSON

it('should respond with JSON data', function (done) {
  request(server)
    .get('/about/jv')
    .expect(200)
    .end(function (err, response) {
      assert.equal(response.header['content-type'], 'application/json; charset=utf-8');
      assert.deepEqual(response.body, {
        "data":{
        "username":"hellojv"}
      });
      done();
    });

but as mentioned above, if you want to use sinon then use the mock library. The example uses Mocha and supertest.

Upvotes: 0

Johannes Merz
Johannes Merz

Reputation: 3342

You want to stub your controller middlewares i guess. As you didn't provide any server side code, i just asume some things:

app.get('/', rootController.get);

Now you want to stub this controller:

it('responds to /', function testSlash(done) {
  const rootController = require('./path/to/your/controller');
  const rootControllerStub = sinon.stub(rootController, "get",
    function(req, res, next){
      res.status(200).json({stubbed: 'data'});
    });
  request(server)
    .get('/')
    .expect(200)
    .expect({stubbed: 'data'})
    .end(done);
});

Upvotes: 5

Related Questions