简体   繁体   English

如何在 NodeJS 中设置 MongoDB 进行集成测试?

[英]How to setup MongoDB for integration tests in NodeJS?

I am writing integration tests for application written in NodeJS with MongoDB.我正在为使用 MongoDB 用 NodeJS 编写的应用程序编写集成测试。

On CI server I would like to have some sort of embedded MongoDB for faster performance and easier control.在 CI 服务器上,我想要某种嵌入式 MongoDB 以提高性能和更容易控制。 Currently I have MongoDB on other server, but tests are slow.目前我在其他服务器上有 MongoDB,但测试速度很慢。 Before each test I need to drop all collections.在每次测试之前,我需要删除所有集合。 I am using mongoose as ORM.我使用猫鼬作为 ORM。

So far I have only found embedded MongoDB for Java.到目前为止,我只找到了嵌入式 MongoDB for Java。

As of this writing, I'd recommend using mongodb-memory-server .在撰写本文时,我建议使用mongodb-memory-server The package downloads a mongod binary to your home directory and instantiates a new memory-backed MondoDB instance as needed.该软件包将 mongod 二进制文件下载到您的主目录,并根据需要实例化一个新的内存支持的 MondoDB 实例。 This should work well for your CI setup because you can spin up a new server for each set of tests, which means you can run them in parallel.这应该适用于您的 CI 设置,因为您可以为每组测试启动一个新服务器,这意味着您可以并行运行它们。

See the documentation for details on how to use it with mongoose.有关如何将其与 mongoose 一起使用的详细信息,请参阅文档。


For readers using jest and the native mongodb driver , you may find this class useful:对于使用jest和本机 mongodb 驱动程序的读者,您可能会发现此类很有用:

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());

Following the "don't use test doubles for types you don't own" principle, consider continue using a real MongoDB instance for your integration test.遵循“不要对您不拥有的类型使用测试替身”原则,考虑继续使用真正的 MongoDB 实例进行集成测试。 Look at this nice article for details.有关详细信息,请查看这篇不错的文章

Our team has been stubbing out the mongo skin calls.我们的团队一直在剔除 mongo 皮肤调用。 Depending on your testing packages you can do the same thing.根据您的测试包,您可以做同样的事情。 It takes a little bit of work but it is worth it.这需要一点工作,但这是值得的。 Create a stub function and then just declare what you need in your test.创建一个存根函数,然后在测试中声明您需要的内容。

   // Object based stubbing
    function createObjStub(obj) {
      return {
        getDb: function() {
         return {
            collection: function() {
              var coll = {};

              for (var name in obj) {
                var func = obj[name];

                if (typeof func === 'object') {
                  coll = func;
                } else {
                  coll[name] = func;
                }
              }

              return coll;
            }
          };
        }
      }
   }; 
    // Stubbed mongodb call
      var moduleSvc = new ModulesService(createObjStub({
        findById: function(query, options, cb) {
          return cb({
             'name': 'test'
           }, null);
           //return cb(null, null);
        }
      }),{getProperties: function(){return{get: function(){} }; } });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM