With the Global Setup/Teardown and Async Test Environment APIs, Jest can work smoothly with MongoDB.

A jest-mongodb example

The basic idea is to:

  • Spin up in-memory mongodb server
  • Export a global variable with mongo URI
  • Write tests for queries / aggregations using a real database ✨
  • Shut down mongodb server using Global Teardown
    Here's an example of the GlobalSetup script
  1. // setup.js
  2. const path = require('path');
  3. const fs = require('fs');
  4. const {MongoMemoryServer} = require('mongodb-memory-server');
  5. const globalConfigPath = path.join(__dirname, 'globalConfig.json');
  6. const mongod = new MongoMemoryServer({
  7. autoStart: false,
  8. });
  9. module.exports = async () => {
  10. if (!mongod.isRunning) {
  11. await mongod.start();
  12. }
  13. const mongoConfig = {
  14. mongoDBName: 'jest',
  15. mongoUri: await mongod.getConnectionString(),
  16. };
  17. // Write global config to disk because all tests run in different contexts.
  18. fs.writeFileSync(globalConfigPath, JSON.stringify(mongoConfig));
  19. // Set reference to mongod in order to close the server during teardown.
  20. global.__MONGOD__ = mongod;
  21. };

Then we need a custom Test Environment for Mongo

  1. // mongo-environment.js
  2. const NodeEnvironment = require('jest-environment-node');
  3. const path = require('path');
  4. const fs = require('fs');
  5. const globalConfigPath = path.join(__dirname, 'globalConfig.json');
  6. class MongoEnvironment extends NodeEnvironment {
  7. constructor(config) {
  8. super(config);
  9. }
  10. async setup() {
  11. console.log('Setup MongoDB Test Environment');
  12. const globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8'));
  13. this.global.__MONGO_URI__ = globalConfig.mongoUri;
  14. this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName;
  15. await super.setup();
  16. }
  17. async teardown() {
  18. console.log('Teardown MongoDB Test Environment');
  19. await super.teardown();
  20. }
  21. runScript(script) {
  22. return super.runScript(script);
  23. }
  24. }
  25. module.exports = MongoEnvironment;

Finally we can shut down mongodb server

  1. // teardown.js
  2. module.exports = async function() {
  3. await global.__MONGOD__.stop();
  4. };

With all the things set up, we can now write our tests like this:

  1. // test.js
  2. const {MongoClient} = require('mongodb');
  3. let connection;
  4. let db;
  5. beforeAll(async () => {
  6. connection = await MongoClient.connect(global.__MONGO_URI__);
  7. db = await connection.db(global.__MONGO_DB_NAME__);
  8. });
  9. afterAll(async () => {
  10. await connection.close();
  11. await db.close();
  12. });
  13. it('should aggregate docs from collection', async () => {
  14. const files = db.collection('files');
  15. await files.insertMany([
  16. {type: 'Document'},
  17. {type: 'Video'},
  18. {type: 'Image'},
  19. {type: 'Document'},
  20. {type: 'Image'},
  21. {type: 'Document'},
  22. ]);
  23. const topFiles = await files
  24. .aggregate([
  25. {$group: {_id: '$type', count: {$sum: 1}}},
  26. {$sort: {count: -1}},
  27. ])
  28. .toArray();
  29. expect(topFiles).toEqual([
  30. {_id: 'Document', count: 3},
  31. {_id: 'Image', count: 2},
  32. {_id: 'Video', count: 1},
  33. ]);
  34. });

原文: https://jestjs.io/docs/en/mongodb