5

I'm using something very similar to the following to execute a series of API tests using Mocha. This is great, but it requires making a separate API call for each test. I want to use the same API call and run multiple tests against that response. I've been reading that you can use before to do it, but none of the examples around the web actually show it working with API calls?

var chai = require('chai');
var request = require('request');
var async = require('async');
var assert = chai.assert,
    expect = chai.expect,
    should = chai.should();

describe('/', function () {
  it('should return 200', function (done) {
    request.get('http://localhost:8000', function (err, res, body) {
      res.should.have.status(200);
      done();
    });
  });

  it('should say "Hello, world!"', function (done) {
    request.get('http://localhost:8000', function (err, res, body) {
      body.should.have.property('type', 'aType');
      done();
    });
  });
});
brandonscript
  • 68,675
  • 32
  • 163
  • 220

1 Answers1

6

You could do this with a before function like so...

var chai = require('chai');
var request = require('request');
var async = require('async');
var assert = chai.assert,
    expect = chai.expect,
    should = chai.should();

describe('/', function () {
  var firstRequest;

  before(function(done) {
    request.get('http://localhost:8000', function(err, res, body) {
      firstRequest = {
        err:err,
        res:res,
        body:body
      };
      done();
    });
  });

  it('should return 200', function (done) {
    firstRequest.res.should.have.status(200);
    done();
  });

  it('should say "Hello, world!"', function (done) {
    firstRequest.body.should.have.property('type','aType');
    done();
  });
});

However, unless you have a really good reason to do this, I think you're better off just combining the tests.

var chai = require('chai');
var request = require('request');
var async = require('async');
var assert = chai.assert,
    expect = chai.expect,
    should = chai.should();

describe('/', function () {
  it('should return 200 and say "Hello, world!"', function (done) {
    request.get('http://localhost:8000', function (err, res, body) {
      res.should.have.status(200);
      body.should.have.property('type', 'aType');
      done();
    });
  });
});

If the test fails Mocha will report the specific reason why it failed even though there are two assertions.

Daniel
  • 38,041
  • 11
  • 92
  • 73
  • 1
    Thought about doing that, but when I have 10 or so body assertions, then it gets really ugly trying to describe what's going on. Was hoping to have a nice clean list of tests in a row with the applicable descriptions. – brandonscript Nov 24 '14 at 02:18
  • Oddly `should.have.status` doesn't seem to play nicely doing it this way - not sure why. Hopefully I figure it out lol! – brandonscript Nov 24 '14 at 02:43
  • Just one update: you don't need `done` on the tests if you are just checking the response. There is nothing async going on inside the `it()` clauses in your first example. – deitch Nov 24 '14 at 13:38
  • Also, I tend to separate them (your first style), since it makes it easier to isolate problems, e.g. if one part fails, it is a separate `it(should)` and thus easier to isolated with an `it.only()` and debug – deitch Nov 24 '14 at 13:39
  • @deitch nice call, I had copied that code from the web and didn't notice it. – brandonscript Nov 24 '14 at 20:16