Search code examples
javascriptmocha.jssupertest

Why won't my supertest calls chain?


It never hits the inner call, so done() isn't being called and my Mocha test is timing out. Why is this?

testUsers.forEach(function(loggedInUser) {
  var describeStr;
  if (loggedInUser && loggedInUser.username === 'a') {
    describeStr = 'Tangos API (role: user)';
  }
  else if (loggedInUser && loggedInUser.username === 'admin') {
    describeStr = 'Tangos API (role: admin)';
  }
  else {
    describeStr = 'Tangos API (not logged in)';
  }

  describe(describeStr, function() {
    var id;

    beforeEach(function(done) {
      if (!loggedInUser) {
        return done();
      }

      agent
        .post('/users')
        .send(loggedInUser)
        .end(function(err, res) {
          console.log('err: ', err); // null
          console.log('res.text: ', res.text); // correct
          agent
            .post('/tangos')
            .send(testTango)
            .end(function(err, result) {
              console.log('inner'); // never hits here
              if (err) {
                return done(err);
              }
              return done(); // never hits here, so mocha tests time out
            })
          ;
        })
      ;
    });

Using async doesn't work either:

async.series([
  function() {
    agent
      .post('/users')
      .send(loggedInUser)
      .end(function(err, res) {
        console.log('err: ', err); // null
        console.log('res.text: ', res.text); // correct
      })
    ;
  }, function() {
    agent
      .post('/tangos')
      .send(testTango)
      .end(function(err, result) {
        console.log('inner'); // never hits here
      })
    ;
  }
], done);

Solution

  • I see 2 possible issues here. First of all, your async series is missing the callbacks that are needed in each function.

    async.series([
      function(callback) {
        agent
          .post('/users')
          .send(loggedInUser)
          .end(function(err, res) {
            console.log('err: ', err); // null
            console.log('res.text: ', res.text); // correct
            callback(); // Need to call the callback here.
          })
        ;
      }, function(callback) {
        agent
          .post('/tangos')
          .send(testTango)
          .end(function(err, result) {
            console.log('inner'); // never hits here
            callback(); // Need to call callback here too.
          })
        ;
      }
    ], done);
    

    I ran this exact test with my own endpoint it worked fine.

    The first code snippet looks okay and works fine for me. I would venture to say you are timing out before it gets the chance to finish. By default, the timeout is 2000ms. It would make sense that 2 API calls don't finish in 2 seconds. To increase the timeout, simply put

    this.timeout(5000);
    

    in the describe block to increase the timeout value.