Mocha doesn't get right app variable with async return

Issue

I’m trying to make some unit tests using mocha on my api built with express.
I have a main function (in the main.js file) which is asynchronous because I needed to wait for some actions before doing others.
Everything works well but when I export the app

main().then((server) => {
    module.exports = server
})

Mocha doesn’t get the server at the right time because It throws me the error before All my logs

below : the main function (in the main.js file):

async function main() {
    await brokerUtils.initBroker(); //Initialization of client mqtt
    await connectToMongo()
    brokerUtils.manageMessages(); // Listenening to messages

    app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));


    app.get('/', (req, res) => {
        res.json({ mes: 'Hello world' });
    });

    /**Routers */
    app.use('/api/bowl', authenticateToken, bowlRouter);
    app.use('/api/meal', authenticateToken, mealRouter);
    app.use('/api/user', authenticateToken, userRouter);

    app.post('/api/register', validationMiddleware(registerSchema, ['body']), register);
    app.post('/api/auth', validationMiddleware(loginSchema, ['body']), authenticate);
    app.post('/api/recover', validationMiddleware(recoverSchema, ['body']), recoverAccount);
    app.put('/api/password', validationMiddleware(changePasswordSchema, ['body']), changePassword);
    app.post('/api/refreshToken', refreshToken);

    logger.info("Application is up")
    return app.listen(2000)
}

here’s my test file :

const app = require("../main");
const expect = require("chai").expect;
const chai = require("chai")
const chaiHttp = require("chai-http");
chai.use(chaiHttp)

const requester = chai.request(app).keepOpen();

describe("authentication tests", () => {
    it("test register a new user", (done) => {
        const userInfos = {
            username: "toto",
            email: "[email protected]",
            password: "toto"
        }
        requester.post("/api/register").send(userInfos).end((err, res) => {
            expect(err).to.be.null;
            expect(res).to.have.status(200);
            done()
        })
    })
})

my logs :
enter image description here

Solution

There is a problem with the export from the main module. You cannot define the export inside a promise. You can export a function that launches the application instead:

module.exports = {
    getServer:() => main()
}

Then in your test import that function, get the server instance and pass it to chai.request()

const { getServer } = require("../main");
const expect = require("chai").expect;
const chai = require("chai")
const chaiHttp = require("chai-http");
chai.use(chaiHttp)


describe("authentication tests", () => {
    let requester;
    before(async () => {
        const server = await getServer();
        requester = chai.request(server).keepOpen();
    })

    it("test register a new user", (done) => {
        const userInfos = {
            username: "toto",
            email: "[email protected]",
            password: "toto"
        }
        requester.post("/api/register").send(userInfos).end((err, res) => {
            expect(err).to.be.null;
            expect(res).to.have.status(200);
            done()
        })
    })
})

Answered By – antonku

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published