node.jsexpresschaisupertest

Request body undefined in supertest


I am testing an express API with supertest. I am trying to pass in body parameters into the test, as can be seen in the code snippets below, but it appears that the body parameters don't get passed in correctly since I get an error message that the body parameters are undefined.

Running the test with command mocha --recursive returns the following error:

Cannot read property 'email' of undefined


Below is the code from file email-suite.js referencing supertest

'use strict';
var express = require("express");
var bodyParser = require('body-parser');
var mongoose = require("mongoose");

var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var supertest = require("supertest");
var chai = require("chai");
var should = chai.should();

var api = require("../server.js");

describe("Email Module", function() {
    this.timeout(25000);

    before(function(done){
        mongoose.createConnection(/* connectionstring */);

        mongoose.connection.on('open', function(err) {
            if(err) console.log(err);
            console.log('connected to server');
        });

        done();
    });

    it("Check Email Count", function(done) {
        var body = { email: "email@email.com" };

        supertest(api)
            .post("/emailCount")
            .set('Accept', 'application/json')
            .send(body)  // body is undefined
            .expect(200)
            .expect('Content-Type', /json/)
            .end(function(err, res) {
                if(err) return done(err);
                res.body.count.should.equal(2);
                done();
            });
    });
});

Below is the code from file email-api.js

'use strict';
var express = require("express");
var bodyParser = require('body-parser');
var router = express.Router();
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

router.post('/emailCount', function(req, res) {
    var email = req.body.email; // req.body is undefined
}

module.exports = router;

Below is the code from the file server.js

var express = require("express");
var app = express();

app.set("port", process.env.PORT || 3000);

var router = require("./user/email-api");

app.use('/', router);

app.listen(app.get("port"), function() {
    console.log("App started on port " + app.get("port"));
});

module.exports = app;

Solution

  • Put body-parser always after express object and before every routes in main server file like this

     var app = express();
     app.use(bodyParser.json());
     app.use(bodyParser.urlencoded({extended: true}));
    

    //Router task start from here

    Other wise always will get undefined since router call first and body parsed later.