How to export node express app for chai-http

chai-http multiple requests
chai http status
chai-http async/await
chai-http close server
supertest
chai.request is not a function
chai request headers
chai-http typescript

I have an express app with a few endpoints and am currently testing it using mocha, chai, and chai-http. This was working fine until I added logic for a pooled mongo connection, and started building endpoints that depended on a DB connection. Basically, before I import my API routes and start the app, I want to make sure I'm connected to mongo.

My problem is that I'm having trouble understanding how I can export my app for chai-http but also make sure there is a DB connection before testing any endpoints.

Here, I am connecting to mongo, then in a callback applying my API and starting the app. The problem with this example is that my tests will start before a connection to the database is made, and before any endpoints are defined. I could move app.listen and api(app) outside of the MongoPool.connect() callback, but then I still have the problem of there being no DB connection when tests are running, so my endpoints will fail.

server.js

import express from 'express';
import api from './api';
import MongoPool from './lib/MongoPool';
let app = express();
let port = process.env.PORT || 3000;
MongoPool.connect((err, success) => {
    if (err) throw err;
    if (success) {
        console.log("Connected to db.")
        // apply express router endpoints to app
        api(app);
        app.listen(port, () => {
            console.log(`App listening on port ${port}`);
        })
    } else {
        throw "Couldnt connect to db";
    }

})
export default app;

How can I test my endpoints using chai-http while making sure there is a pooled connection before tests are actually executed? It feels dirty writing my application in a way that conforms to the tests I'm using. Is this a design problem with my pool implementation? Is there a better way to test my endpoints with chai-http?

Here is the test I'm running

test.js

let chai = require('chai');
let chaiHttp = require('chai-http');
let server = require('../server').default;;
let should = chai.should();


chai.use(chaiHttp);
//Our parent block
describe('Forecast', () => {
/*
  * Test the /GET route
  */
  describe('/GET forecast', () => {
      it('it should GET the forecast', (done) => {
        chai.request(server)
            .get('/api/forecast?type=grid&lat=39.2667&long=-81.5615')
            .end((err, res) => {
                res.should.have.status(200);
              done();
            });
      });
  });

});

And this is the endpoint I'm testing

/api/forecast.js

import express from 'express';
import MongoPool from '../lib/MongoPool';
let router = express.Router();
let db = MongoPool.db();

router.get('/forecast', (req, res) => {
    // do something with DB here
})

export default router;

Thank you for any help

After receiving some good feedback, I found this solution works best for me, based on Gomzy's answer and Vikash Singh's answer.

In server.js I'm connecting to the mongo pool, then emitting the 'ready' event on the express app. Then in the test, I can use before() to wait for 'ready' event to be emitted on the app. Once that happens, I'm good to start executing the test.

server.js

import express from 'express';
import bodyParser from 'body-parser';
import MongoPool from './lib/MongoPool';
let app = express();
let port = process.env.PORT || 5000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

(async () => {
    await MongoPool.connect();
    console.log("Connected to db.");
    require('./api').default(app);
    app.listen(port, () => {
        console.log(`Listening on port ${port}.`)
        app.emit("ready");
    });
})();

export default app;

test.js

//Require the dev-dependencies
import chai from 'chai';
import chaiHttp from 'chai-http';
import server from '../src/server'; 
let should = chai.should();
chai.use(chaiHttp);

before(done => {
  server.on("ready", () => {
    done();
  })
})
describe('Forecast', () => {
  describe('/GET forecast', () => {
    it('it should GET the forecast', (done) => {
      chai.request(server)
          .get('/api/forecast?type=grid&lat=39.2667&long=-81.5615')
          .end((err, res) => {
              res.should.have.status(200);
            done();
          });
    });
  });

});

Testing A Node/Express Application With Mocha & Chai, Testing A Node/Express Application With Mocha & Chai We also needed to include chai-HTTP which is a plugin that allows us to run HTTP integrations with chai assertions. getSingleStudent);export default routes;. Open in app. Become a member. Sign in. In this article, we’ll be writing a simple Node/Express API application while incorporating testing using the mocha & chai JavaScript testing packages.

Express app is an instance of EventEmitter so we can easily subscribe to events. i.e app can listen for the 'ready' event.

Your server.js file will look like below,

import express from 'express';
import api from './api';
import MongoPool from './lib/MongoPool';
let app = express();
let port = process.env.PORT || 3000;

app.on('ready', function() {
  app.listen(3000, function() {
    console.log('app is ready');
  });
});

MongoPool.connect((err, success) => {
  if (err) throw err;
  if (success) {
    console.log('Connected to db.');
    // apply express router endpoints to app
    api(app);

    // All OK - fire (emit) a ready event.
    app.emit('ready');
  } else {
    throw 'Couldnt connect to db';
  }
});

export default app;

Testing Express with Mocha and Chai, Testing our app allows us to keep control of every cha a server app using Express, and we'll test it with Mocha and Chai. node app.js. It will start listening on port 4000. We can send it a request by visiting http://localhost:4000 in our app.js file is being required in the test, but isn't exporting anything. In this post we are going to create a server app using Express, and we’ll test it with Mocha and Chai. Testing our app allows us to keep control of every change in the code while we are in the development stage. Building our app. We’ll write a program that listens to requests, and responds appropriately.

Just create a function below to connect to mongo and, make it returns a promise. then use await to wait for it to connect and return. the function could be like that

function dbconnect(){
    return new Promise(function(resolve, reject){

    MongoPool.connect((err, success) => {
    if (err) reject(err);
    if (success) {
        resolve({'status' : true})
    } else {
        reject(new Error({'status' : false}))
    }

})
    })
}

And then, use

await dbconnect();
api(app);
app.listen(port, () => {
    console.log(`App listening on port ${port}`);
})

now await line will wait for the function to connect to DB and then return success or error in case of failure. This is a kind of solution you can use, but I would not recommend you to do this, what we actually do is.

create services and use those services in routes, don't write DB code directly in routes.

and

while writing tests for routes mock/stub those services, and test services separately in other test cases, where you just pass DB object and service will add functions on that DB objects, so in tests you can connect to DB and pass that object to those services to test functions, it will give you additional benefit, if you want to use dummy/test DB for testing you can set that in test cases.

Test a Node RESTful API with Mocha and Chai ― Scotch.io, Lastly Chai HTTP addon allows Chai library to easily use assertions on HTTP than a server with node.js, the test-related packages mocha, chai, chai-http Create a file in /app/model/ called book.js and paste the following code: At the end we export the object using a faster syntax which pairs key and� what is Chai HTTP. Chai-Http is an addon for assertion library Chai which helps in testing Http Requests. This addon is helpful in testing APIs as it helps to test different types of requests like get, post, etc. The latest version of Chai available to use is 4.3.0. To install chai-http to be used with Node.js use

Use Before function in your tests like below :

 describe('Forecast', () => {
  before(function(done){
   checkMongoPool(done); // this function should wait and ensure mongo connection is established.
  });
  it('/GET forecast', function(cb){
  // write test code here ...
  });
});

And you can check mongodb connection like this below methods:

Method 1: just check the readyState property -

mongoose.connection.readyState == 0; // not connected
mongoose.connection.readyState == 1; // connected`

Method 2: use events

mongoose.connection.on('connected', function(){});
mongoose.connection.on('error', function(){});
mongoose.connection.on('disconnected', function(){});

Chai HTTP, Application / Server. You may use a function (such as an express or connect app) or a node.js http(s) server as the foundation for� In this article, we’ll be writing a simple Node/Express API application while incorporating testing using the mocha & chai JavaScript testing packages. Tagged with mocha, chai, testing, node.

You can use running server instead of a express instance.

Start your server with a private port, then take tests on the running server.

ex: PORT=9876 node server.js

In your test block, use chai.request('http://localhost:9876') (replace with your protocol, server ip...) instead of chai.request(server).

Chapter 9. Testing Express applications, Testing in Node.js applications has three major parts: the real code (written by You're using two modules here: Mocha (www.mochajs.org) and Chai (http://chaijs .com). The last line is the only thing that might seem new: you export the app. The reason we export the express application in the last line is because we want to be able to automatically launch our server during testing and import our app instance into Chai HTTP. Unit Testing. To create our unit tests, we will be using Mocha, Chai, and Chai HTTP modules.

Typescript, Express, Mocha & Chai Error while testing, Response) => { res.status(200).send("SUCCESS"); }); export default app; import * as chai from 'chai'; import chaiHttp = require('chai-http'); chai.use( chaiHttp); import Testing Node and Express with TypeScript, Mocha, Chai and Sinon.js,� I am a full-stack web developer working for Taroko Software as front-end web developer and Filestack Tech Evangelist. When not coding I may be spotted in a gym lifting or planning to conquer the world LOL.

Test with mocha & chai-http: "Cannot read property server" : node, Hi, I'm creating an API with Node, Express and Mongoose. getApp() export default app app.ts export class App { private static readonly PORT: number = 3000� Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. APIs With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.

Mocha, Mocha is a feature-rich JavaScript test framework running on Node.js and in the The latter example uses Chai as Promised for fluent promise assertions. 4 times this.retries(4); beforeEach(function () { browser.get('http://www.yahoo.com'); } For example, suppose your app deliberately exposes a global named app and� Testing A Node/Express Application With Mocha & Chai. Testing requires that you write tests which cover various input a software might receive and the corresponding output to them. That way you can be sure that the application is running exactly how you intended it to and this can prevent a lot of bugs.

Comments
  • HI Isaac. From your test, you can initialize your app and wait till app is connected, so, inside server.js you can define an "initialize" method returning a promise / callback / async function and calling this method when you start the tests (also you can put logic to see if the server is running or not inside initialize method to start listening for connections, connecting to mongodb, etc) Regards
  • Seems to be the best solution. Thanks for sharing.
  • Thank you, emitting and listening for an event was for the most part the solution to my problem.
  • Although I'm not using mongoose, thank you for this because I didn't know that before() was even a thing haha, but it helped a lot with my solution.
  • Thanks for this answer, I should've looked at the documentation better because I thought I could only pass a server object to chai.request.