In-memory MongoDB for test?

前端 未结 2 742
野趣味
野趣味 2021-02-05 08:26

I am writing some integration and system tests for my NodeJS application using a MongoDB database. The test framework I use is Mocha and Supertest. Is it possible to setup Mongo

相关标签:
2条回答
  • 2021-02-05 08:28

    I recommend using mongodb-memory-server.

    I have a DB file that is shared over the whole project, so I have to have it testable as well.

    //db.js
    
    import mongoose from 'mongoose';
    import bluebird from 'bluebird';
    
    module.exports = {
      mongoose,
      init: () => {
          mongoose.Promise = bluebird;
      },
      connect: async database => {
          try {
              const conn =  await mongoose.connect(
                  database,
                  { useNewUrlParser: true }
              );
    
              //eslint-disable-next-line
              console.log(`MongoDb Connected on: ${database}`);
    
              return conn;
          } catch (err) {
              //eslint-disable-next-line
              console.log('Error to connect on mongo', err);
          }
      },
      disconnect: async () => await mongoose.connection.close()
    };
    

    To be used (db.js) on my tests I've created a test-helper.js file.

    'use strict';
    import MongodbMemoryServer from 'mongodb-memory-server';
    import db from '../src/db';
    
    const server = new MongodbMemoryServer();
    
    const createDB = async () => {
        try {
           const url = await server.getConnectionString();
           db.connect(url);
        } catch (err) {
          throw err;
        }
     };
    
     const destroyDB = () => {
       db.disconnect();
    
     };
    
     module.exports = {
        createDB,
        destroyDB
     }; 
    }
    

    So, my tests always have before and after (to create and destroy de DB), something like:

    import { createDB, destroyDB } from '../test-helper';
    before(() => {
      createDB();
    });
    after(() => {
      destroyDB();
    });
    

    Hope it is helpful.

    The project I'm using it: https://github.com/abdalla/node-auth

    0 讨论(0)
  • 2021-02-05 08:50

    You can accomplish this using mongodb-memory-server. The package downloads a mongod binary to your home directory and instantiates a new memory-backed MondoDB instance as needed. For each test file you can spin up a new server which means you can run them all parallel.


    For readers using jest and the native mongodb driver, you may find this class useful:

    const { MongoClient } = require('mongodb');
    const { MongoMemoryServer } = require('mongodb-memory-server');
    
    // Extend the default timeout so MongoDB binaries can download
    jest.setTimeout(60000);
    
    // List your collection names here
    const COLLECTIONS = [];
    
    class DBManager {
      constructor() {
        this.db = null;
        this.server = new MongoMemoryServer();
        this.connection = null;
      }
    
      async start() {
        const url = await this.server.getUri();
        this.connection = await MongoClient.connect(url, { useNewUrlParser: true });
        this.db = this.connection.db(await this.server.getDbName());
      }
    
      stop() {
        this.connection.close();
        return this.server.stop();
      }
    
      cleanup() {
        return Promise.all(COLLECTIONS.map(c => this.db.collection(c).remove({})));
      }
    }
    
    module.exports = DBManager;
    

    Then in each test file you can do the following:

    const dbman = new DBManager();
    
    afterAll(() => dbman.stop());
    beforeAll(() => dbman.start());
    afterEach(() => dbman.cleanup());
    

    I suspect this approach may be similar for other testing frameworks.

    0 讨论(0)
提交回复
热议问题