supertest: When status code expectation fails, can't figure out which request failed

In my Mocha tests I use before() hooks to send a number of requests to create data required for the actual tests. When one of the requests fails I end up with supertest’s internal stack trace, which doesn’t tell which request failed. The only indication of error is that one of the requests returned with unexpected status code.

Here’s an example

var request = require('supertest');
var url = 'www.example.com';

request(url)
  .get('/')
  .expect(200)
  .end(function(err) {
    if (err) console.log(err.stack);
  });

request(url)
  .get('/test')
  .expect(200)
  .end(function(err) {
    if (err) console.log(err.stack);
  });

which gives the following stack trace:

$ node test.js 
Error: expected 200 "OK", got 404 "Not Found"
    at Test._assertStatus (/my/path/node_modules/supertest/lib/test.js:232:12)
    at Test._assertFunction (/my/path/node_modules/supertest/lib/test.js:247:11)
    at Test.assert (/my/path/node_modules/supertest/lib/test.js:148:18)
    at assert (/my/path/node_modules/supertest/lib/test.js:127:12)
    at /my/path/node_modules/supertest/lib/test.js:124:5
    at Test.Request.callback (/my/path/node_modules/supertest/node_modules/superagent/lib/node/index.js:831:3)
    at Stream.<anonymous> (/my/path/node_modules/supertest/node_modules/superagent/lib/node/index.js:1049:12)
    at Stream.emit (events.js:117:20)
    at Unzip.<anonymous> (/my/path/node_modules/supertest/node_modules/superagent/lib/node/utils.js:108:12)
    at Unzip.emit (events.js:117:20)

Is this an expected behaviour or this is something I can try to fix?

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 20
  • Comments: 20 (3 by maintainers)

Most upvoted comments

Shame this is closed @rimiti. I encountered the exact same issue today. At a minimum, I’d like to include the line in my spec file which caused the error! Currently I just get this:

at Test._assertHeader (node_modules/supertest/lib/test.js:247:12)
      at Test._assertFunction (node_modules/supertest/lib/test.js:281:11)
      at Test.assert (node_modules/supertest/lib/test.js:171:18)
      at Server.assert (node_modules/supertest/lib/test.js:131:12)
      at emitCloseNT (net.js:1664:8)
      at _combinedTickCallback (internal/process/next_tick.js:136:11)
      at process._tickDomainCallback (internal/process/next_tick.js:219:9)

What’s the current advice for how best to handle this in a Mocha test?

if it helps, you can stop performing expectations with supertest and use chai or jest instead.

const res = await request(url).get('/')
expect(res.status).to.eq(200)

This will return the exact file and line of the failed assertion. A bit more verbose… but it makes debugging much faster.

Always a good assumption to have, @jpbochi. I will check it out later this week and open the PR. Stay tuned.

I couldn’t wait, sorry. Here’s my solution: https://github.com/visionmedia/supertest/pull/690

Have the same problem with stack traces using e.g. expect(200) method. As this problem is already ~3 years old and, as mentioned by @CatBakun, it cannot be solved by Bluebird-Promises, I have to stop using this package 😦

Nice, good stuff, thanks for PR. My solution was very similar to yours: wrapping the assert functions and preserving the stack from a new Error instance.

Would a PR fixing this one be of interest here, @rimiti? I quickly fixed my version locally and the output is now the following:

  expected 200 "OK", got 404 "Not Found"
Error
    at Test.expect (/project/node_modules/supertest/lib/test.js:86:18)
    at Context.<anonymous> (/project/test/controllers/MyController.test.js:84:50)  <--- only meaningful line
    at callFn (/project/node_modules/mocha/lib/runnable.js:358:21)
    at Test.Runnable.run (/project/node_modules/mocha/lib/runnable.js:346:5)
    at Runner.runTest (/project/node_modules/mocha/lib/runner.js:621:10)
    at /project/node_modules/mocha/lib/runner.js:745:12
    at next (/project/node_modules/mocha/lib/runner.js:538:14)
    at /project/node_modules/mocha/lib/runner.js:548:7
    at next (/project/node_modules/mocha/lib/runner.js:430:14)
    at Immediate._onImmediate (/project/node_modules/mocha/lib/runner.js:516:5)
    at processImmediate (internal/timers.js:461:21)
    at process.topLevelDomainCallback (domain.js:138:15)
    at process.callbackTrampoline (internal/async_hooks.js:124:14)

Not sure it if would fix this one, it is still a bunch of non-sense but at least I can quickly know where the error failed. Maybe someone with more experience could get it better later.

I use the following function to throw an error in end() callback handler:

var _ = require('lodash');
var checkStatusCode = function(res, expectedStatus) {
  if (!expectedStatus) expectedStatus = 200;
  if (res.status === expectedStatus) return res;
  var description = res.req.method + ' ' + res.req.path;
  var data = (res.request && res.request._data) ? res.request._data : null;
  var paddedDataStr = (data && _.isPlainObject(data)) ? (' ' + JSON.stringify(data)) : '';
  var resStr = (_.isPlainObject(res.body) ? JSON.stringify(res.body) : res.body);
  throw new Error(description + paddedDataStr + ' ' + res.statusCode + ', expected ' + expectedStatus + '. Reason: '  + resStr);
};

This gives missing request details and proper stack trace. Of course it’s up to personal preferences.