Supertest: expressjs - res.status is not a function TypeError

Created on 17 May 2017  路  13Comments  路  Source: visionmedia/supertest

Hello,

I used supertest with tape, sinon, proxyquire & expressJS, I got this error :

error: res.status is not a function TypeError: res.status is not a function
    at <path>\index.ts:26:11
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
(node:21020) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: res.sendStatus is not a function

this is my route function

router.get('/customers', middleware, (req: express.Request, res: express.Response) => {
  let options = {
    uri: url,
    method: 'GET',
  };
  request(req, options).then(body => {
    if (body) {
      res.status(200).send(body);
    }
  }).catch((error) => {
    res.sendStatus(500);
  });
});

my unit test

import * as test from 'tape';
import * as sinon from 'sinon';
import * as request from 'supertest';
import * as proxyquire from 'proxyquire';

const requestStub = sinon.stub();

const stubResponse = {
  statusCode: 200,
  body: { body: 'body' }
};

const api = proxyquire('./', { 'api-request': requestStub });
requestStub.returns(Promise.resolve(stubResponse));

test('Get /customers', (assert) => {

  const agent = request.agent(api);

  agent
    .get('/customers')
    .expect(200)
    .set('Accept', 'application/json')
    .end((err, res) => {
      var expectedThings =
        {
          "some" : "data"
        };
      var actualThings = res.body;

      assert.error(err, 'No error');
      assert.same(actualThings, expectedThings, 'Retrieve list of things');
      assert.end();
    });
});

Do you have any idea?

Most helpful comment

Fixed, in my case..
Just add "next" to the variables list (err, req, res, next)

app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({error: 'an error occurred'});
});

From documentation: https://expressjs.com/ru/api.html

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don鈥檛 need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

All 13 comments

I encountered the same error when applying supertest on a express route.

const routes = express.Router();
routes.get('/', ()=> res.status(200).send('blub'))
request(routes).get('/').end() // status not a function
request(app.use(routes)).get('/').end() // works

Same issue. The solution of @nikhedonia brings it to work

Hi @rimiti , would you mind giving a working example that adapts @nikhedonia 's PoC above?

Additionally, can you explain why arrow functions are not supported in this context? Since arrow function are now (at time of writing) the default way to declare functions in node (the function keyword is being phased out of most example code and books), can you please explain the design considerations of not having supertest work with arrow functions in this particular example?

I understand you're quite busy and appreciate the help 馃槃

Having the same issue even with function() {}

Fixed, in my case..
Just add "next" to the variables list (err, req, res, next)

app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({error: 'an error occurred'});
});

From documentation: https://expressjs.com/ru/api.html

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don鈥檛 need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

Having the same issue @rimiti . Could u please reopen the issue or look into #596 ?

he tendido el mismo problema y lo que pasa es que tienes definida la request del get con req y el de la funcion request tambien esto deveria funcionar:
router.get('/customers', middleware, (req: express.Request, res: express.Response) => {
let options = {
uri: url,
method: 'GET',
};
request(otherRequest, options).then(body => { // change a definition of request
if (body) {
res.status(200).send(body);
}
}).catch((error) => {
res.sendStatus(500);
});
});

I also have the same problem.

router.post('/signin',(req,res,next)=>{
    const username=req.body.username;
    const password=req.body.password;

    // check vaild input
    if(!username||!password){
        return res.status(422).json({err:"Please add all the fields."})
    }

    User.findOne({userId:username})
    .then(saveduser=>{
        console.log(saveduser)
        if(saveduser){
            const hash=saveduser.password;
            bcrypt.compare(password,hash,(err,res)=>{
                if(err)
                    console.log(err);

                if(res)
                    return res.status(422).json({error:"This line is causing error!"})
                else res.json({err:"Email/password do not match!"})
            })
        }
    .catch(err=>{
        console.log(err);
    })
})

Error

TypeError: res.status is not a function

Can, somebody explain me why i am getting this error.

@Ats1999 You are using res variable two times. One is the response object and the second is the bcrypt result. Rename the second res (in bcrypt callback) so as to not overwrite your response object.

@mathurin59000 Thankyou, I was doing same mistake

@iLyxa3D Thanks

I faced the issue in production
the response request was
res.status(401)
I just added unauthorized
res.status(401).send({auth:false})

Fixed, in my case..
Just add "next" to the variables list (err, req, res, next)

app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({error: 'an error occurred'});
});

From documentation: https://expressjs.com/ru/api.html

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don鈥檛 need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

Thank you so much ! The solution as well as your explanation helped!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jonathanong picture jonathanong  路  4Comments

UniverseHan picture UniverseHan  路  4Comments

rkmax picture rkmax  路  5Comments

ryami333 picture ryami333  路  4Comments

Shingaz picture Shingaz  路  5Comments