18

我正在尝试编写一个测试来测试连接到 mongo 的方法,但我实际上并不想让 mongo 运行并实际连接到它以使我的测试成功通过。

这是我当前的测试,当我的 mongo 守护进程运行时它是成功的。

describe('with a valid mongo string parameter', function() {
    it('should return a rejected promise', function(done) {
        var con = mongoFactory.getConnection('mongodb://localhost:27017');
        expect(con).to.be.fulfilled;
        done();
    });
});

mongoFactory.getConnection 代码:

getConnection: function getConnection(connectionString) {

      // do stuff here

        // Initialize connection once
        MongoClient.connect(connectionString, function(err, database) {
          if (err) {
            def.reject(err);
          }

          def.resolve(database);
        });

      return def.promise;
    }
4

2 回答 2

44

有几个与使用 MongoDB 作为数据存储的单元测试代码相关的 SO 答案:

我将尝试整合这些解决方案。

前言

首先,您应该希望 MongoDB 在执行测试时运行。MongoDB 的查询语言很复杂,因此需要针对稳定的 MongoDB 实例运行合法查询,以确保您的查询按计划运行并且您的应用程序正确响应结果。但是,考虑到这一点,您永远不应该针对生产系统运行测试,而应该针对集成环境的外围系统运行测试。这可以与您的 CI 软件在同一台机器上,或者只是相对接近它(就进程而言,不一定是网络或地理上)。

此 ENV 可能占用空间小并且完全在内存中运行(资源 1)(资源 2),但不一定需要与您的生产 ENV 相同的性能特征。(如果您想进行性能测试,无论如何都应该在与 CI 不同的环境中进行处理。)

设置

  • mongod专门为 CI安装服务。如果需要考虑 repl 集和/或分片(例如,写入问题、不使用$isolated等),则可以通过运行多个mongod实例(1 个配置,2x2 数据用于 shard+repl)和一个mongos实例来模拟集群环境带有一些 init.d 脚本/调整或类似 docker 的同一台机器。
  • 在您的应用程序中使用特定于环境的配置(通过 .json 文件嵌入,或者在 /etc、/home/user/.your-app 或类似的地方)。您的应用程序可以根据节点环境变量(如NODE_ENV=int. 在这些配置中,您的数据库连接字符串会有所不同。如果您使用特定于 env 的配置,请开始这样做作为抽象应用程序运行时设置(即“local”、“dev”、“int”、“pre”、“prod”等)的一种方式。我可以根据要求提供样品。
  • 在您的应用程序/测试套件中包含面向测试的夹具。如链接问题之一所述,MongoDB 的 Node.js 驱动程序支持一些帮助程序库:mongodb-fixturesnode-database-cleaner. Fixtures 为测试提供了一个工作且一致的数据集:将它们视为一个引导程序。

构建/测试

  1. 使用类似的东西清理关联的数据库node-database-cleaner
  2. mongodb-fixtures.
  3. 执行您的构建和测试。
  4. 重复。

另一方面...

如果您仍然认为运行 MongoDB 是正确的方法(而且您不会是唯一的方法),那么使用 ORM 从驱动程序抽象您的数据存储调用是您最好的选择(对于整个应用程序,而不仅仅是测试) . 例如,model声称是数据库不可知论之类的东西,尽管我从未使用过它。使用这种方法,您仍然需要fixturesenv 配置,但是您不需要安装 MongoDB。这里需要注意的是,您受制于您选择的 ORM。

于 2014-09-02T04:38:19.840 回答
-2

你可以试试tingodb

TingoDB 是一个嵌入式 JavaScript 进程内文件系统或内存数据库,在 API 级别向上兼容 MongoDB。

于 2016-05-25T11:01:54.920 回答