4

I've been really enjoying Istanbul and experimenting with other Node.js coverage libraries as well, but I have an issue. Nearly all of my unit tests are HTTP calls to my API like so:

    it('should update the customer', function (done) {
        superagent.put('http://myapp:3000/api/customer')
            .send(updatedData)
            .end(function (res) {
                var customer = res.body;
                expect(res.statusCode).to.equal(200);
                expect(customer.name).to.equal(updatedData.name);
                done();
            });
    });

As opposed to actually requiring the customers.js file and calling updateCustomer directly. Testing the endpoint makes much more sense to me, as it not only tests updateCustomer, but also the routes, controllers, and everything else involved.

This works fine, but the problem is that I can't seem to see a way for any code coverage tool to recognize these tests. Is there any way for Istanbul or anything else to recognize these Mocha tests? If not, what is the convention? How do you test endpoints and still use code coverage tools?

1 Answer 1

3

The issue is that you're using superagent, whereas you should be using supertest to write unit tests. If you use supertest, istanbul will correctly track code coverage.

Some sample code to get you started:

'use strict';

var chai = require('chai').use(require('chai-as-promised'));
var expect = chai.expect;
var config = require('../../config/config');
var request = require('supertest');

var app = require('../../config/express')();

describe('Test API', function () {
  describe('test()', function() {
    it('should test', function(done) {
      request(app)
        .get('/test')
        .query({test: 123})
        .expect('Content-Type', /json/)
        .expect(200)
        .end(function(err, res){
          expect(err).to.equal(null);
          expect(res.body).to.equal('whatever');
          done();
        });
    });

    it('should return 400', function(done) {
      request(app)
        .get('/test/error')
        .query({})
        .expect('Content-Type', /json/)
        .expect(400, done);
    });
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Is the line with require('../../config/express')() supposed to load all of the server code? Is it how Istanbul figures where the server code is? Thanks!
The original code actually did var app = require('./config/express')(config);, it was a function that returned an express instance given a config object. You can just do var app = express(); instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.