I’m learning to create RestAPI’s using NodeJS and MongoDB from this tutorial, and from the repo they have provided[which has quite a lot of updates from the post], I further modified it to do UnitTesting of my Mongo server with Jest and SuperTest.
The major changes I’ve made to the repo before adding mine is:
Move the listen logic to a start.js
, while in package.json
make this the main file
start.js
const { app } = require("./index");
// Setup server port
var port = process.env.PORT || 8080;
app.listen(port, function () {
console.log("Running RestHub on port " + port);
});
module.exports = {app};
wrap the app in the index.js by an export after moving the logic.
index.js
app.use('/api', apiRoutes);
// Launch app to listen to specified port
// app.listen(port, function () {
// console.log("Running RestHub on port " + port);
// });
module.exports = {app};
package.json
{
"name": "resthub2",
"version": "2.0.0",
"description": "A Node App demonstrating simple RESTFul API implementation",
"main": "start.js",
"scripts": {
"test": "jest",
"start": "node start.js"
},
"keywords": [
"API",
"resful",
"json",
"node",
"mongodb",
"express"
],
"author": "David Inyang-Etoh",
"license": "ISC",
"dependencies": {
"@shelf/jest-mongodb": "^1.2.3",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"jest": "^26.4.2",
"mongoose": "^5.6.4",
"supertest": "^5.0.0"
}
}
I followed the special instructions to connect Jest and SuperTest to MongoDB and added these 2 files.
jest.config.js
module.exports = {
"preset": "@shelf/jest-mongodb"
};
contactController.test.js
const {MongoClient} = require('mongodb');
const {app} = require('./index'); // Link to your server file
const supertest = require('supertest');
const request = supertest(app);
const mongoose = require("mongoose");
const Contact = require("./contactModel");
describe('insert', () => {
let connection;
let db;
beforeAll(async (done) => {
connection = await MongoClient.connect(global.__MONGO_URI__, {
useNewUrlParser: true,
});
db = await connection.db(global.__MONGO_DB_NAME__);
Contact.deleteMany({}, (err) => {
done();
});
});
afterAll((done) => {
console.log("After all?");
// await connection.close();
mongoose.connection.close();
// await db.close();
done();
});
it('should insert a doc into collection', async (done) => {
try {
const item = {};
item["name"] = "John 3";
item["email"] = "john@example.org";
item["phone"] = "12345678";
item["gender"] = "Male";
const response2 = await request
.post('/api/contacts')
.send(item);
console.log(response2.status);
console.log("Response2 done");
const response = await request.get("/api/contacts");
console.log(`Weird response status is ${response.status}`);
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(1);
done();
} catch (error) {
console.log(error);
}
}, 30000);
});
However, my tests do not terminate even though I would pass all(which is just 1), and gives me the following message
Jest did not exit one second after the test run has completed. This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
Have tried most of the suggestions in here such as runInBand, closing the connection with mongoose instead, but it is still not terminating. Does anyone have a fix to my issue?