I'm trying to setup a custom Jest test environment where I can connect to the database once before tests start running and disconnect from it after all tests finish. I would like to avoid using helper functions in beforeAll()
and afterAll()
hooks in every test file. Below is how my current setup looks like. When I run the test it is failing due to readyState being 0 which stands for disconnected. What am I missing?
jest.config.js
module.exports = {
testEnvironment: './mongo-environment'
}
mongo-environment.js
const mongoose = require('mongoose')
const NodeEnvironment = require('jest-environment-node')
class MongoEnvironment extends NodeEnvironment {
constructor (config) {
super(config)
}
async setup () {
await this.setupMongo()
await super.setup()
}
async teardown () {
await this.teardownMongo()
await super.teardown()
}
runScript (script) {
return super.runScript(script)
}
setupMongo () {
return new Promise((resolve, reject) => {
mongoose.connect('mongodb://localhost/test')
.then(mongoose => {
const db = mongoose.connection
Promise
.all(Object.keys(db.collections).map(name => db.dropCollection(name)))
.then(resolve)
.catch(reject)
})
.catch(reject)
})
}
teardownMongo () {
return mongoose.disconnect()
}
}
module.exports = MongoEnvironment
example.spec.js
const mongoose = require('mongoose')
describe('test', () => {
it('connection', () => {
expect(mongoose.connection.readyState).toBe(1)
})
})
I have got this to work using combination of setupFilesAfterEnv and testEnvironment and global object.
Setup your DB connection and store the URL in the global object in your custom-environment.js : ( please refer Jest doc for deets )
// my-custom-environment
const NodeEnvironment = require('jest-environment-node');
const { MongoMemoryServer } = require('mongodb-memory-server');
class CustomEnvironment extends NodeEnvironment {
constructor(config, context) {
super(config, context);
this.testPath = context.testPath;
this.docblockPragmas = context.docblockPragmas;
this.db = {}
}
async setup() {
await super.setup();
this.db = await MongoMemoryServer.create()
this.global.MONGO_URI = this.db.getUri()
}
async teardown() {
await this.db.stop()
await super.teardown();
}
getVmContext() {
return super.getVmContext();
}
}
module.exports = CustomEnvironment;
In your setup file that you will run after environment has been setup, configure your mongoose to connect to the global URI that you set previously.
jest.config.js :
module.exports = {
setupFilesAfterEnv : ['./setup-unitTest-db.js']
}
setup-unitTest-db.js :
require('dotenv').config();
const mongoose = require('mongoose');
const mongooseConfig = { useNewUrlParser: true, domainsEnabled: true, useUnifiedTopology: true }
mongoose
.connect( global.MONGO_URI, mongooseConfig)
.then(() => {
mongoose.set('useFindAndModify', false)
})
afterAll (async () => {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
})
And finally, tell Jest to use your custom test environment file by providing the complete path to your environment file by adding the docblock on top of your test file thusly :
// this goes in your test suite
/**
* @jest-environment ./nodeWithMongo
*/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With