Craig Otis Craig Otis - 21 days ago 10
Javascript Question

Mocha tests using superagent + promises timeout rather than fail with 'expect'

I'm using

mocha
to run a number of integration tests against an external web service. I use
superagent-promise
for the request/response handling, and I'm using
expect
as my assertion library.

For some of these tests I need to chain a large number of requests together, so the promises have been very helpful. However I'm noticing that my tests are now failing with a timeout (and no error message) rather than with the error message itself. As a simple example:

it('[MESSAGES-1] cannot be posted without an auth token', function(done) {
agent.post(config.webRoot + '/rooms/ABC/messages').send({
content: 'This is a test!'
}).end().then(function(res) {
// Not expected
}, function(err) {
expect(err.status).toBe(401)
done()
})
})


Works as expected and passes:

Messages
✓ [MESSAGES-1] cannot be posted without an auth token


However if I alter my assertion to expect a different status code:

expect(err.status).toBe(200) // This should fail


Then the test fails with a timeout!

1) Messages [MESSAGES-1] cannot be posted without an auth token:
Error: timeout of 1000ms exceeded. Ensure the done() callback is being called in this test.


Is this a common problem? Is there a workaround or tweak I can make? I don't want to lose the ability to use promises.

Answer

Is this a known issue?

This is actually not an issue.

The problem is that expect(err.status).toBe(200) throws an error that is swallowed inside the .then and which causes the code to never reach done(). You should restructure you code to the following:

it('[MESSAGES-1] cannot be posted without an auth token', function(done) {
    agent.post(config.webRoot + '/rooms/ABC/messages').send({
      content: 'This is a test!'
    }).end()

    .then(function(res) {
      // Not expected
    }, function(err) {
      expect(err.status).toBe(401)
      done()
    })
    .catch(function(err) {
        done(err); //report error thrown in .then
    })
  })

This way you catch and report the error thrown by expect(err.status).toBe(200).

Comments