pierreaurelemartin
pierreaurelemartin

Reputation: 1682

Ping an express + sequelize server with chai-http

I'm having issue on setting up tests with Express and Sequelize. I'm using Mocha + Chai for tests. I'm just trying to ping for now.

Code of server.js :

const express = require('express');
const Sequelize = require('sequelize');
const bodyParser = require('body-parser');

const db = require('./config/db');

const app = express();
const router = express.Router();
const PORT = 8000;

//Use body parser for express
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

const sequelize = new Sequelize(db.database, db.user, db.password, {
  host: db.host,
  dialect: 'mysql',
  operatorsAliases: false,
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
});

sequelize
  .authenticate()
  .then(() => {
    //Import Routes
    require('./app/routes/')(router, sequelize);

    router.get('/', (req, res) => {
      res.json('Welcome to Dickson Connect API :)');
    })

    //Make express Listen
    app.listen(PORT, () => {
      console.log('We are live on ' + PORT);
    })

  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });

//For chai testing
module.exports = app;

The server is working.

and the test.js :

const chai = require('chai');
const chaitHttp = require('chai-http');
const server = require('../../server');

const should = chai.should();

chai.use(chaitHttp);

describe('/GET', () => {

  it('should display a welcome message', (done) => {
    chai.request(server)
    .get('/')
    .then( (res) => {

      res.should.have.status(200);

      done();
    })
    .catch( err => {
      throw err;
    })
  })
})

I believe at least part of the problem is that my server is returning a sequelize instance containing the express app which might not be the usual case. Though, the sequelize is just a promise which I'm waiting for in my chai test, using then instead of end.

this is the error I'm getting :

/GET (node:35436) UnhandledPromiseRejectionWarning: AssertionError: expected { Object (domain, _events, ...) } to have status code 200 but got 404 at chai.request.get.then (/Applications/MAMP/htdocs/api_dickson/app/routes/index.test.js:16:23) at at process._tickCallback (internal/process/next_tick.js:188:7) (node:35436) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:35436) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. Executing (default): SELECT 1+1 AS result We are live on 8000 1) should display a welcome message

0 passing (2s) 1 failing

1) /GET should display a welcome message: Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

No need to tell you I'm starting with those testing stuff (finally...) and therefore, I'm not getting everything yet. Thanks a lot for your help !

PAM

Upvotes: 1

Views: 557

Answers (1)

Florian V.
Florian V.

Reputation: 61

The UnhandledPromiseRejectionWarning you have comes from your test, try to do .then(done, done) after the assertion block instead of calling done() and adding a .catch block.

it('should display a welcome message', (done) => {
  chai.request(server).get('/')
  .then((res) => {
    res.should.have.status(200);
  })
  .then(done, done);
})

Also, about the 404, it's because you set your routes inside the sequelize.authenticate() promise, so when you export your app for the tests, the routes aren't set up. Just move the routes definition (and add a app.use('/', router); statement aswell, else your routes won't be used) above the Promise.

(...)
const sequelize = new Sequelize(...);

require('./app/routes/')(router, sequelize);
router.get('/', (req, res) => {
  res.json('Welcome to Dickson Connect API :)');
})

app.use("/", router);

sequelize
.authenticate()
.then(() => {
  //Make express Listen
  app.listen(PORT, () => {
    console.log('We are live on ' + PORT);
  })
})
.catch(err => {
  console.error('Unable to connect to the database:', err);
});

//For chai testing
module.exports = app;

Upvotes: 1

Related Questions