Reputation: 1207
I'm having this issue, all test pass successfully, but in the end, the process never ends. And what I can see is that there are always two mongod
process instances running.
I'm using mongodb-memory-server
library to mock the database connections, last versions of mongodb
and hapijs
environment.
const { expect } = require ('@hapi/code');
const lab = exports.lab = require ('@hapi/lab').script ();
const { it, describe, after, before } = lab;
const Sinon = require ('sinon');
const DAO = require ('./index');
const CaseBaseDao = require ('case-base-dao'); //from private npm repo
let baseDaoFindStub;
let updateOneStub;
describe ('Profiles DAO', () =>
{
before (async ({ context }) =>
{
const { MongoClient } = require ('mongodb');
const { MongoMemoryServer } = require ('mongodb-memory-server');
const mongoServerInstance = new MongoMemoryServer ({ instance: { port: 27018, dbName: 'administration' } });
const url = await mongoServerInstance.getConnectionString ();
const dbClient = await MongoClient.connect (url);
const collection = await dbClient.db ().createCollection ('profiles');
await collection.insertMany (require ('./examples/profiles.json'));
const dao = DAO () (dbClient.db ());
context.dbClient = dbClient;
context.mongoServerInstance = mongoServerInstance;
context.sandbox = Sinon.createSandbox ();
context.dao = dao;
baseDaoFindStub = context.sandbox.stub (CaseBaseDao.BaseDao.prototype, 'find').resolves ();
updateOneStub = context.sandbox.stub (dao.collection, 'updateOne').resolves ();
});
after (async ({ context: { sandbox, dbClient, mongoServerInstance } }) =>
{
await dbClient.close (); // only added for debug purposes
await mongoServerInstance.stop (); // only added for debug purposes
sandbox.restore ();
});
it ('Should expose DAO methods', ({ context: { dao } }) =>
{
expect (dao).to.be.an.object ();
expect (dao.findByEmail).to.exist ();
expect (dao.find).to.exist ();
expect (dao.findByQuery).to.exist ();
expect (dao.updateOneById).to.exist ();
expect (dao.addSmartPerformanceDashboards).to.exist ();
expect (dao.deleteSmartPerformanceDashboards).to.exist ();
expect (dao.updateSmartPerformanceDashboards).to.exist ();
});
});
There are a lot more of tests, but if I only execute this one, it gets stucked at the end.
And if I try to close connection manually in the after
block, these are the errors that I get:
For the await dbClient.close()
message:"Illegal invocation"
stack:"TypeError: Illegal invocation\n at handleWriteReq (internal/stream_base_commons.js:46:26)\n at writeGeneric (internal/stream_base_commons.js:139:15)\n at Socket._writeGeneric (net.js:771:11)\n at Socket._write (net.js:783:8)\n at doWrite (_stream_writable.js:431:12)\n at writeOrBuffer (_stream_writable.js:415:5)\n at Socket.Writable.write (_stream_writable.js:305:11)\n at Connection.write ({path}/node_modules/mongodb/lib/core/connection/connection.js:265:21)\n at {path}/node_modules/mongodb/lib/core/connection/pool.js:1208:40\n at checkStatus ({path}/node_modules/mongodb/lib/core/connection/pool.js:732:21)\n at Pool.destroy ({path}/node_modules/mongodb/lib/core/connection/pool.js:739:3)\n at Server.destroy ({path}/node_modules/mongodb/lib/core/topologies/server.js:897:15)\n ...
For the await mongoServerInstance.stop ();
message:"Method Promise.prototype.then called on incompatible receiver #"
stack:"TypeError: Method Promise.prototype.then called on incompatible receiver #\n at Promise.then ()"
I've tried almost everything: change ports, use promises instead of async/await, avoid the use of Sinon and stubs (just in case), etc.. and I'm running out of ideas.
I'm using this exact same code to mock databases in other projects, and it works just fine, without any need of close the database connections manually, it just does automatically.
This is happening in my local environment as well as it does in the Bitbucket pipelines, so, discarded to be something related to my computer.
Upvotes: 0
Views: 1092
Reputation: 1207
Finally solved it.
Not sure why this happens, but the solution was not to close MongoDB connections using the mongo instance related vars through @hapi/lab context
, but defining them outside the before
block. So:
let baseDaoFindStub;
let updateOneStub;
let mongoServerInstance; // Now defined here
let dbClient; // Now defined here
describe ('Profiles DAO', () =>
{
before (async ({ context }) =>
{
const { MongoClient } = require ('mongodb');
const { MongoMemoryServer } = require ('mongodb-memory-server');
mongoServerInstance = new MongoMemoryServer ({ instance: { port: 27018, dbName: 'administration' } });
const url = await mongoServerInstance.getConnectionString ();
dbClient = await MongoClient.connect (url);
const collection = await dbClient.db ().createCollection ('profiles');
await collection.insertMany (req
...
...
...
after (async ({ context: { sandbox } }) => // Don't get vars from context
{
sandbox.restore ();
await dbClient.close ();
await mongoServerInstance.stop ();
});
Not the first time I have this kind of problems using @hapi/lab context
, so, be careful with it!
Upvotes: 1