Skip to content

11. Testing with Mocha and Supertest

Nick Doiron edited this page Apr 25, 2016 · 1 revision

Install testing libraries to replace and extend Node's built-in testing:

npm install mocha chai supertest --save-dev

Remember how we used BabelJS to support new JavaScript language features? Mocha won't know how to run your code without being prompted to use Babel. Change your npm test script to: mocha --compilers js:babel-core/register

Testing your first successful page return

At the end of app.js, we should be exporting the app:

module.exports = app;

In a new test directory, create test/profile.js and give it the following template:

// use Chai's assert and not the assert built into NodeJS
const assert = require('chai').assert;

// connect to your app
const app = require('../app.js');

// create a session using supertest
const request = require('supertest').agent(app.listen());

describe('while logged out', function() {
  it('returns a good homepage', function(done) {
    request.get('/')  // the homepage
      .expect(200)    // successful return
      .end(function(err, res) {
        // run your tests on the content here
        assert.include(res.text, 'welcome to my app');

        // call done() to confirm that any async tests are completed, and we can move on to the next test
        done(err);
      });
  });
});

Now when you run npm test it should start up the app and verify that the body of the page includes "welcome to my app".

Let's make more tests for what I should see while logged out: user profiles and images. In each test, we should create a test user and image, and delete them before continuing to the next test.

// helper function to set up a user
function createUser(username, callback) {
  var u = new User({
    test: true,
    name: username,
    posted: null
  });
  u.save(function(err) {
    callback(err, u);
  });
}

// helper function to retrieve a user profile
function requestProfile(username, callback) {
  request.get('/profile/' + username)
    .expect(200)
    .end(callback);
}

// helper function to delete all test users
function wrapup(done, err) {
  User.remove({ test: true }, function(removalError) {
    if (done) {
      done(err || removalError);
    }
  });
}

describe('while logged out', function() {
  it('indicates when user is missing', function(done) {
    // we didn't create this user, so it should raise an error:
    requestProfile('test_user_name', function(err, res) {
      if (err) {
        return wrapup(done, err);
      }

      // not finding the user is a good thing - we haven't created the user yet
      assert.include(res.text, 'can\'t find that user');
      wrapup(done);
    });
  });

  it('shows user name but no photos', function(done) {
    // 1. create the user, then
    createUser('test_user_name', function(err) {
      // 2. make sure it was created successfully
      if (err) {
        return wrapup(done, err);
      }

      // 3. request the profile page, then
      requestProfile('test_user_name', done, function(err, res) {
        // 4. make sure it loaded successfully
        if (err) {
          return wrapup(done, err);
        }

        // 5. check the response for sample text
        assert.include(res.text, 'test');
        assert.include(res.text, 'hasn\'t posted yet!');

        // 6. delete test data
        wrapup(done);
      });
    });
  });
});

Clone this wiki locally