supertest: Cannot read property 'status' of undefined

When sending test request with expected status code and getting response with invalid content type (eg. header says application/json, but server sends xml/html), the Test.prototype._assertStatus fails while getting status from res (which is undefined).

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 51
  • Comments: 40 (2 by maintainers)

Most upvoted comments

I got this error when testing over a secure connection. I fixed it by adding NODE_TLS_REJECT_UNAUTHORIZED=0 as an env var on the test run.

For those wondering why this happens, it can happen because ‘127.0.0.1’ is not listed as a valid IP in your certificate. The underlying error is … Hostname/IP doesn’t match certificate’s altnames: "IP: 127.0.0.1 is not in the cert’s list: " However, you will not see this error message - Just the spurious and much disliked …

Cannot read property ‘status’ of undefined

Hope this helps someone. God bless.

Just got this error, and my problem is that I forgot the slash in get path: supertest(server).get('favicon.ico') gets me…

TypeError: Cannot read property 'status' of undefined
at Test.Object.<anonymous>.Test._assertStatus (node_modules/supertest/lib/test.js:268:10)
      at Test.Object.<anonymous>.Test._assertFunction (node_modules/supertest/lib/test.js:286:11)
      at Test.Object.<anonymous>.Test.assert (node_modules/supertest/lib/test.js:175:18)
      at Server.assert (node_modules/supertest/lib/test.js:132:12)

putting the slash in, supertest(server).get('/favicon.ico') …the test works as expected.

I traced the issue down to logic that applies assertions. It’s supposed to early-exit with an error if there was an error, but something causes it to run the assertions anyway and it fails because response is undefined when there’s an error:

callback that performs assertions gets resError { Error: connect ECONNREFUSED 127.0.0.1:80
          at Object._errnoException (util.js:1041:11)
          at _exceptionWithHostPort (util.js:1064:20)
          at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1153:14)
        code: 'ECONNREFUSED',
        errno: 'ECONNREFUSED',
        syscall: 'connect',
        address: '127.0.0.1',
        port: 80,
        response: undefined } res undefined

Maybe it fails because the un-intended effect of forgetting the slash means that it will try to connect to “http://favicon.ico” which isn’t a server?

Either way it needs some logic hardened in Test.assert (or whatever runs through the array of assertions and applies them) and a friendly error message saying it Couldn't connect to http://favicon.ico:80 to run the tests instead of throwing some IP number out - there is no way to know what that means without reading the whole library.

I have the same issue with node 7.2.1:

     TypeError: Cannot read property 'status' of undefined
      at Test._assertStatus (node_modules/supertest/lib/test.js:263:10)
      at Test._assertFunction (node_modules/supertest/lib/test.js:281:11)
      at Test.assert (node_modules/supertest/lib/test.js:171:18)
      at assert (node_modules/supertest/lib/test.js:131:12)
      at node_modules/supertest/lib/test.js:128:5
      at Test.Request.callback (node_modules/superagent/lib/node/index.js:615:12)
      at ClientRequest.<anonymous> (node_modules/superagent/lib/node/index.js:567:10)
      at Socket.socketErrorListener (_http_client.js:309:9)
      at onwriteError (_stream_writable.js:346:10)
      at onwrite (_stream_writable.js:364:5)
      at WritableState.onwrite (_stream_writable.js:90:5)
      at fireErrorCallbacks (net.js:471:13)
      at Socket._destroy (net.js:512:3)
      at WriteWrap.afterWrite (net.js:806:10)

It fails sometimes. About 1 to 10 times. My test looks pretty straight forward:

it('should fail because the token has already been used', function (done) {
            request(server)
                .post(`${apiPath}/${token}/actions/create`)
                .attach('upload', filePath)
                .expect(400)
                .end((err, res) => {
                    if (err) return done(err);
                    expect(res.body.success).to.be.false;
                    done();
                })
        });

My deps:

  "dependencies": {
    "cron": "^1.1.1",
    "debug": "~2.2.0",
    "dotenv": "^2.0.0",
    "express": "^4.14.0",
    "extract-zip": "^1.5.0",
    "formidable": "^1.0.17",
    "jsonfile": "^2.4.0",
    "mysql": "^2.11.1",
    "promise": "^7.1.1",
    "request": "^2.79.0",
    "shelljs": "^0.7.5"
  },
  "devDependencies": {
    "babel-cli": "^6.18.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-stage-2": "^6.18.0",
    "babel-register": "^6.18.0",
    "chai": "^3.5.0",
    "mocha": "^3.2.0",
    "supertest": "^2.0.1"
  }

https://github.com/visionmedia/supertest/pull/446 should help reveal the underlying error here.

Tried updating various dependencies including body-parser - same issue for me. 👎

This is how I solved it using Promises from Supertest@2.0.0:

it('should return 404 Not Found for missing resources', function() {
  return req.get('/this/is/not/found')
    .expect(404)
    .expect(function(res) {
      assert.equal(res.body.message, 'Resource Not Found');
    });
});

Like @danday74 said this issue is present when using HTTPS without NODE_TLS_REJECT_UNAUTHORIZED=0.

Will there be a fix for this soon? Does anyone have a workaround for this?

This only seems to happen with POST and PUT requests, for me at least.

I’ve tried upgrading relevant packages (express, bluebird, http-status, mocha, node, supertest), using promises as suggested above, downgrading to node v5/v4, getting latest mac OS and xcode - still getting the same supertest error:

Unhandled rejection TypeError: Cannot read property 'status' of undefined

Here is one example that fails - this used to work, I don’t understand why this is no longer working.

it('should work', (done) => {
    request(app)
      .post('/api/create')
      .set('Authorization', JWT_VALID)
      .send(CREATE_OBJ)
      // .expect(httpStatus.OK)
      .expect(200)
      .then((res) => {
        expect(res.body).to.be.an('object');
        done();
      });
  });
});

This is completely blocking me atm. Maybe superagent is the way to go.

Here’s a traceback:


     TypeError: Cannot read property 'status' of undefined
      at Test._assertStatus (node_modules/supertest/lib/test.js:229:10)
      at Test._assertFunction (node_modules/supertest/lib/test.js:247:11)
      at Test.assert (node_modules/supertest/lib/test.js:148:18)
      at Server.assert (node_modules/supertest/lib/test.js:127:12)
      at net.js:1277:10    


I’m getting this when the response body has a malformed JSON. It’s good that the test fails, but it’s for the wrong reasons and also with a cryptic message. Would it be possible to not try to parse the body unless I’m reading from it? At least don’t give a catastrophic failure just because the response body can’t be parsed.

Looks like #348 is a fix

Updating body-parser (https://www.npmjs.com/package/body-parser) to 1.16.0 (in my case) did the trick for me.