rewiremock
rewiremock copied to clipboard
Something like cache problem
Hi! I'm mocking mongodb in my mocha tests with rewiremock and mongo-mock. I can rewire my wrapper that contains the mongo lib, but when another module calls that file, it doesn't have the started configuration like database, collections... I think it's something like cached modules, but I don't know what to do anymore. I have:
common.js
require('app-module-path').addPath(`${process.cwd()}/src`);
global.rewiremock = require('rewiremock').default;
const {addPlugin, plugins} = require('rewiremock');
addPlugin(plugins.usedByDefault);
addPlugin(plugins.nodejs);
global.TestDbHelper = require('./dbHelper');
dbHelper.js
const mongoMock = require('mongo-mock');
class TestDbHelper {
constructor() {
this.mongodb = rewiremock.proxy('lib/mongo', {
'mongodb': mongoMock
});
}
async connect() {
rewiremock.enable();
await this.mongodb.connect('mongodb://localhost:27017/test', { db: 'test' });
}
async disconnect() {
rewiremock.disable();
}
}
lib/mongo.js
const { MongoClient, ObjectID } = require('mongodb');
const config = require('config');
const mongoConfig = config.get('mongodb');
module.exports = {
async connect (uri, options = {}) {
return new Promise(async (resolve, reject) => {
this.uri = uri;
this.client = await MongoClient.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
...options
})
this.db = this.client.db()
return resolve(this.client);
})
},
async getCollection (name) {
if (!this.client || !this.client.isConnected()) {
await this.connect(this.uri)
}
return this.db.collection(name)
}
}
When the feature that is being tested calls getCollection
, this.client
is undefined
and all will fail.
CALLER: at TestDbHelper.connect
mongo-mock:mongo_client connecting localhost:27017/test +0ms
mongo-mock:collection initializing instance of `system.namespaces` with 1 documents +1ms
mongo-mock:collection initializing instance of `system.indexes` with 0 documents +0ms
mongo-mock:db test open +353ms
mongo-mock:collection initializing instance of `system.namespaces` with 1 documents +1ms
mongo-mock:collection initializing instance of `system.indexes` with 0 documents +0ms
app:mongo:connector MongoDB Connected +0ms
CALLER: getCollection
(node:9060) UnhandledPromiseRejectionWarning: MongoParseError: URI malformed, cannot be parsed
supressed...
mongo-mock:db undefined open +93ms
Can you help me?
rewiremock.enable();
/ rewiremock.disable();
are definetely not working as you might expected them, as 1) they have nothing to do 2) they react only to require
call between them, which is not happening.
Actually, from what I can see 'mongodb
has got replaced by mongoMock
. So what is not working in this case?
In the log, we can see connection (caller TestDbHelper.connect), after this, my test that calls getCollection
. In this point, we don't have this.client
and this.uri
anymore (populated in connection). So, he tried to connect again and use undefined this.uri
and we will have a failure.
I tested that flow without rewiremock (using conditionals with process.env.NODE_ENV
inside code) and It worked. So, I think I'm doing something wrong with rewiremock.
Sorry. The actual test is not visible to me and there is no way I can help here:
- what calls
getCollection
? - what initializes
TestDbHelper
? How it's been used? - the only way to set
this.url
is to callconnect
, the logic ingetCollection
just cannot work!