skip to Main Content

I want to start incorporating testing with Jest in my projects but I’m having a hard time getting this test to work. When I run it I get this error thrown.

thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

       5 |
       6 |
    >  7 | test('Create a new user', async()=>{
         | ^
       8 |
       9 |    await request(app).post('/').send({
      10 |         name:'alex',

      at Object.test (tests/user.test.js:7:1)

The code in the test file looks like this

const app = require('../app');
const usersRoute = require('../routes/users');
const request = require('supertest');



test('Create a new user', async()=>{

   await request(app).post('/').send({
        name:'alex',
        email:"[email protected]",
        password:"1234567",
        role:"admin"
    }).expect(201);

})

My app.js file looks like this

const express = require("express");
const colors = require('colors');
const errorHandler = require('./middleware/error');
const morgan = require('morgan');
const localdb = require('./db/bootcampDB');
const fileupload = require('express-fileupload');
const path = require('path');
const cookieParser = require('cookie-parser');

//ROUTES

const reviews = require('./routes/reviews');
const auth = require('./routes/auth')
const bootcamps = require('./routes/bootcamps');
const courses = require('./routes/courses')
const users = require('./routes/users');

const app = express();

app.use(express.json())

if(process.env.NODE_ENV === 'development'){
    app.use(morgan('dev'));
}

localdb();

app.use(fileupload())

//SET static folder
app.use(express.static(path.join(__dirname, 'public')));

app.use('/api/v1/bootcamps', bootcamps);
app.use('/api/v1/courses', courses);
app.use('/api/v1/auth', auth);
app.use('/api/v1/users', users);
app.use('/api/v1/reviews', reviews);

app.use(cookieParser);
app.use(errorHandler)

module.exports = app;

server.js file

const app = require('./app');

const port = process.env.PORT || 4000

const server = app.listen(port, ()=>{
    console.log(`Server running in ${process.env.NODE_ENV} mode on port ${port}`.yellow.bold);
})


process.on('unhandledRejection',(err, promise)=>{
    console.log(`Error: ${err.message}`.red);
    
    //Close server
    server.close(()=>{
        process.exit(1)
    })
})

This particular test needs to go through the "/api/v1/users" route that looks like this

router.route('/').get(advancedResults(User), getUsers).post(createUsers);

That line of of code is in file called uses.js that is in a folder called routes.

user.js file

 const express = require('express');
const {getUsers,getSingleUsers,createUsers, deleteUsers, updateUsers} = require('../controllers/users');
const User = require('../models/user');
const router = express.Router({mergeParams:true});

const {protect, authorize} = require('../middleware/auth')
const advancedResults = require('../middleware/advancedResults');

router.use(protect);
router.use( authorize('admin'))

router.route('/').get(advancedResults(User), getUsers).post(createUsers);

router.route('/:id').get(getSingleUsers).put(updateUsers).delete(deleteUsers);


module.exports = router;

The method it self is in a file called user.js that is in a controllers folder. It looks like this

// @desc   Create user
// @route  POST /api/v1/auth/users
// @access Private/Admin

exports.createUsers = asynHandler(async(req, res, next)=> {
    const user = await User.create(req.body)
     
    res.status(201).json({success:true, data: user})
});

One of the things I’ve done is change what’s being passed into requests. For example if I pass in '/api/v1/users' I don’t get the timed error I get this error

   expected 201 "Created", got 404 "Not Found"

      12 |         password:"1234567",
      13 |         role:"admin"
    > 14 |     }).expect(201);
         |        ^
      15 |
      16 | })
      17 |

      at Object.expect (tests/user.test.js:14:8)
      ----
      at Test._assertStatus (node_modules/supertest/lib/test.js:252:14)
      at node_modules/supertest/lib/test.js:308:13
      at Test._assertFunction (node_modules/supertest/lib/test.js:285:13)
      at Test.assert (node_modules/supertest/lib/test.js:164:23)
      at localAssert (node_modules/supertest/lib/test.js:120:14)
      at node_modules/supertest/lib/test.js:125:7
      at Test.fn [as callback] (node_modules/superagent/src/node/index.js:924:3)
      at IncomingMessage.callback (node_modules/superagent/src/node/index.js:1153:18)

This makes me even more confused because I thought I was telling the program to create data, not find it. If anyone can help me understand Jest and what’s going on here I would greatly appreciate.

Thanks

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out actually someone else helped me figure it out. The error was in the routing. Jest didn't know what route to run and would just timedout when it couldn't locate the route. My request should've been written like this

    test('Create a new user', async () => {
    
        const response = await request(app)
          .post(`/api/v1/auth/register`)
          .send({
            name: 'alex',
            email: '[email protected]',
            password: '1234567',
            role: 'admin',
          }).expect(201);
      });
    

    auth.js routes file

    const express = require('express');
    const {register, login, getMe, getAllUser,forgotPassword, resetPassword, updateDetails, updatePassword} = require('../controllers/auth');
    const { protect } = require('../middleware/auth');
    
    const router = express.Router();
    
    router.get('/allusers',getAllUser);
    router.post('/register', register);
    router.post('/login', login);
    router.get('/me', protect, getMe);
    router.post('/forgotPassword', forgotPassword);
    router.put('/resetpassword/:resettoken', resetPassword);
    router.put('/updatedetails', protect, updateDetails);
    router.put('/updatepassword', protect, updatePassword);
    
    
    module.exports = router;
    

  2. Looks like you are not starting your application in app.js, try to add:

    const server = app.listen(8000, () => console.log('Server listening...'));
    
    module.exports = { app, server };
    

    And specify the full path on the executed test (use the afterAll callback to close the service at the end of tests).

    const { app, server } = require('../app');
    const usersRoute = require('../routes/users');
    const request = require('supertest');
    
    const base_path = 'http://localhost:8000';
    
    describe('/api/v1/users', () => {
    
      afterAll(() => {
        server.close();
      })
    
      test('Create a new user', async () => {
        await request(app)
          .post(`${base_path}/api/v1/users`)
          .send({
            name: 'alex',
            email: '[email protected]',
            password: '1234567',
            role: 'admin',
          })
          .expect(201);
      });
    });
    

    Finally, if you need to send a token to a protected route you can use set:

    await request(app)
      .post(<your-path>)
      .set('Authorization', <your-token>)
      .send({ ... })
      .expect(201);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search