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

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?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 24
  • Comments: 25

Commits related to this issue

Most upvoted comments

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’t 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.

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

@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.

Request is the first parameter, Response the second and Next the third. Invert req and res in your parameters.

Always use (err, req, res, next) in sequence else you would also get this res.status error. app.use((err, req, res, next) => { console.error(err); res.status(500).json({error: ‘an error occurred’}); });

Having the same issue even with function() {}

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 😄

import adminModels from "../../models/admin/adminModels.js";

export const adminRegister = async ( request , response, next)=> {
    const { name, email, phone, password } = request.body;
    try {
        if (!name) {
            return response.status(500).json({
                sucess: false,
                msg: "Name is Required"
            });
        }
        if (!email) {
            return response.status(500).json({
                sucess: false,
                msg: "Email is Required"
            });
        }
        if (!phone) {
            return response.status(500).json({
                sucess: false,
                msg: "Phone is Required"
            });
        }
        if (!password) {
            return response.status(500).json({
                sucess: false,
                msg: "Password is Required"
            });
        }

        // check wheather user exist or not
        const exit = await adminModels.findOne({
            email: email
        });

        if (exit) {
            return response.status(202).json({
                success: "User already Exit",
                msg: exit
            });
        }


        let newAdmin = await adminModels.create(req.body);
        res.json({
            success: true,
            message: 'Admin Register successfully',
            student: newAdmin
        });
    }

    catch (err) {
        console.log(err);
    }
}

TypeError: response.status is not a function

I got this error please help me to solve this issus

Instead of passing directly reducers, pass an object like this, {reducer: reducers} (reducers which is your combineReducers)

code with the error of res.status is not a function TypeError


app.use(function (err, res, req, next) {
  if (err.name === "UnauthorizedError") {
    res.status(401).json({ error: "Unauthorized" });
  }
});

clean code work well

app.use(function (err, req, res, next) {
  if (err.name === "UnauthorizedError") {
    res.status(401).json({error : "Unauthorized"});
  }
});


i don’t know where is the error lol