Description
🚀 Feature Proposal
In addition to the function-initializer style of jest.mock
, support an async variant that accepts a function which returns a promise, and use the resolution from that promise to determine the mocked module's exports:
jest.mock('.../db.js', async () => {
// Where the import() is transpiled by babel - this is not a feature request for
// import support.
const MongoMemoryServer = await import('mongo-memory-server'),
mongoist = await import('mongoist'),
mongod = new MongoMemoryServer(),
uri = await mongod.getConnectionString();
return mongoist(uri);
});
Motivation
Some information that can be known statically or synchronously in applications is only available asynchronously in test cases. To ease development in this case, we could let the module initializer function be asynchronous to avoid problematic hacks. See workaround in Pitch
section.
Additionally, the import
statement isn't a supported statement within the normal module initializer function, and tools like babel refuse to transpile it.
Example
(the same as in 🚀 Feature Proposal
)
jest.mock('.../db.js', async () => {
// Where the import() is transpiled by babel - this is not a feature request for
// import support.
const MongoMemoryServer = await import('mongo-memory-server'),
mongoist = await import('mongoist'),
mongod = new MongoMemoryServer(),
uri = await mongod.getConnectionString();
return mongoist(uri);
});
Pitch
Because this isn't a problem easily solved in the wild world of community ecosystem and support. There are fragile and application-specific ways to work around this problem by altering the application code itself in service to the tests, or by monkey patching external dependencies to make them work asynchronously. This is one such approach to working around this:
jest.mock('.../db.js', () => {
const MongoMemoryServer = require('mongo-memory-server'),
mongoist = require('mongoist'),
mongod = new MongoMemoryServer(),
uri = mongod.getConnectionString(),
db = mongoist(null);
db.connect = async function() {
if (this.connection) {
return this.connection;
}
const connectionString = await uri;
if (this.connectionString === null) {
this.connectionString = connectionString;
}
return mongoist.Database.prototype.connect.call(this);
};
return db;
});
Moreover, it simplifies the adoption of import
over require
for groups that prefer the former, as tools like babel
don't support placing a standard import
statement in the mocked function (babel/babel#10864).