Supertest: Supertest throwing 404, Client says 200

Created on 9 Jul 2015  路  11Comments  路  Source: visionmedia/supertest

I have a route to get all friends in a database as follows:

router.get('/friends', function(req, res, next){
  Friend.find(function(err, friends){
    if(err){ console.log(err); }
    req.data = friends;
    next();
  })
});

Hitting this route with postman returns a list of all friends in the database successfully, and other queries from a web client behave normally. However, with Supertest when I try to test this route, a 404 is returned.

Here is the test:

var app = require('../server'); 
var should = require('should');
var supertest = require('supertest');
var request = supertest(app);


describe('Friends', function(){

  it('Should get all friends.', function(done){
    request
      .get('/friends')
      .expect(200)
      .end(function (err, res){
        res.status.should.equal(200);
        done();
      })
  });

});

Now, about 20% of the time, this test will execute successfully for no given reason. My question: Why does supertest return a 404, when all other methods to access the route return 200?

Most helpful comment

Hi, I'm having the same issue! Some of my routes throw 404 in my tests but when I literally copy/paste it to postman, it works

All 11 comments

+1
I have a similar issue. In my case, I use a rest call in several tests. Sometimes it works, sometimes it gets a 404. I assume, that somehow supertest doesnt realise that the app is not ready yet.

Stunning that this issue is open for over a year. I guess I will drop supertest for superagent.

I'm also having the same issue

+1 it does not work with my error handling middleware

Long shot here, but in my case, the error was caused by koa-cors. That middleware causes Koa to return a 404 if the origins do not match. (I switched to the official kcors gem and all is well now.) Anywho, it might be worth disabling middleware and testing again to see if you can rule out middleware behavior causing a 404 in your test environment.

+1 anyone find a solution to this? I have a restify api that with the same behavior, test = 404, but postman = 200. It looks like the test a are firing before the app is ready, but in restify, as far as i can tell, you cant emit an event for mochas before function.

Hi, I'm having the same issue! Some of my routes throw 404 in my tests but when I literally copy/paste it to postman, it works

@Arinzeokeke im not really sure what the true solution is and off the top of my head dont remember how I specifically fixed this. However, I do use jest now and in jest I use supertest to make the api request. Again I know this is not 'The Solution' but a work around.

const appRoute = require('app-root-path')
const api = require(`${ appRoute }/app`)
const request = require('supertest')

const badReq = { }

it('Should fail validation', () => {
  return request(api)
    .post('/my/route')
    .send(badReq)
    .then(res => {
      expect(res.status).toEqual(400)
    })
})

and thats run by npm test which runs jest.

I am still having the same issue. Is there an update on that issue so far?

I seem to be having this same issue (postman returning 200, supertest returning 404 for patch requests only). I can see this was closed but was this functionality ever resolved?

In my case I am using routing-controllers package, and for some reason the decorators seem to be an issue.

A request to this endpoint returns 200 in Postman, but 404 in supertest:

@Post()
@OnUndefined(200)
public reboard(@CurrentUser() user: User, @Body() body: Reboarding, @Res() res: Response, @Session() session: any) {     
        return undefined;
    }

This one returns 200 in both agents:

@Post()
public reboard(@CurrentUser() user: User, @Body() body: Reboarding, @Res() res: Response, @Session() session: any) {     
        return res.sendStatus(200);
    }

The only difference between both requests is that the first one does not return an 'OK' in the response's body. The second one sends the 'OK' body along.

It can be that supertest does not handle an empty response correctly, but I don't think that is the case.

It is most probably that routing-controllers @OnUndefined decorator is not working properly during tests for some reason. According to the documentation:

If your controller returns void or Promise or undefined it will throw you 404 error. To prevent this if you need to specify what status code you want to return using @OnUndefined decorator.

So it is probable that the decorator is being ignored.

I hope it helps!

For anyone stumbling across this from Google:

Make sure you are using .post() to fetch a post endpoint and .get() for a get endpoint.

I know. Pretty silly, but that was my mistake and why I was getting 400's when postman reported 200

Was this page helpful?
0 / 5 - 0 ratings

Related issues

schm1ty1 picture schm1ty1  路  4Comments

rkmax picture rkmax  路  5Comments

hacker0limbo picture hacker0limbo  路  3Comments

bookercodes picture bookercodes  路  5Comments

mickaeltr picture mickaeltr  路  3Comments