【问题标题】:mocha wait for db connection before running testsmocha 在运行测试之前等待数据库连接
【发布时间】:2022-04-24 22:46:19
【问题描述】:

基本上要运行测试,我需要准备好与 MongoDb 的数据库连接。数据库管理器有一个用于获取连接的 connect 方法和一个用于获取对该连接的引用的 get 方法。 connect 方法应该只在启动时调用一次。这种设计在运行应用程序时运行良好,因为应用程序仅在调用 connect 方法并返回连接时才会启动。

使用 mongo native 的数据库管理器(没有 mongoskin,没有 mongoose)(database.js):

var config = require('../config')
var MongoClient = require('mongodb').MongoClient

var connection = null

module.exports.connect = function () {
  return MongoClient.connect(config.mongodb.uri + config.mongodb.db)
    .then(function (db) {
      connection = db
    })
}

module.exports.get = function () {
  if (!connection) {
    throw new Error('Call connect first!')
  }
  return connection
}

启动应用程序:

var db = require('./services/database');
db.connect()
  .then(function() {
    logger.info("mongodb is running");
    require('./main')
  });

在应用程序中,有服务模块和存储库模块。服务模块在必须使用数据库时需要存储库模块。我有一个 BaseRepository 模块,在其中定义了常见查询 findOne、findAll 等。对于所有 MongoDb 集合,我有一个从 BaseRepository 继承的特定存储库。在构造函数中,我通过调用数据库连接来设置集合。

这意味着当服务模块依赖于存储库模块时,必须调用数据库连接方法。这是问题所在,因为我不知道在调用该连接方法后如何启动所有测试。 如果您认为这是一个设计流程,我愿意接受建议。

测试:

var usersService = require('../../services/rest/UsersService');
describe('IT Test', function () {
})

服务:

var usersRepository = require('../dao/UsersRepository');

存储库:

var db = require('../database');
var BaseRepository = require('./BaseRepository');
var util = require('util');

util.inherits(UsersRepository, BaseRepository);

function UsersRepository() {
    this.collection = db.get().collection('users');  // <====== The connect method has not been called yet
}

基础存储库:

function BaseRepository() {
    this.collection = undefined;
}

BaseRepository.prototype.findOne = function (filters) {
    return this.collection.findOne(filters)
}

【问题讨论】:

  • 如何在测试中调用connect?你有before钩子吗?
  • 我不需要,因为我只需要调用它一次,然后开始所有测试。即使我在before 中调用connect,它也不会解决问题,因为问题是由require(service) -&gt; require(repository) -&gt; constructor 触发的,调用get 而未调用连接。 beforerequire 之后调用。
  • 您可以将代码 (this.collection = db.get().collection('users');) 从存储库构造函数移动到新的 init 方法,并在测试模块中的 before 挂钩中调用此方法。因此,您将拥有一个全局 before,并在每个测试模块中调用 db.connectbefore 以进行 repo 初始化。

标签: node.js mongodb


【解决方案1】:

我最终为所有测试编写了一个包装器

'use strict'
var logger = require('../services/logger')()
var db = require('../services/database')

describe('All tests wrapper', function () {

  it('should pass', function () {
    return db.connect()
      .then(function () {
        logger.info('MongoDB is running')
        require('./agenda/AgendaJobsIT')
        require('./dashboard/DashboardsServiceIT')
        require('./twitter/TwitterServiceTest')
        require('./authentication/TokenServiceTest')
      })
  })

})

【讨论】:

  • 何时关闭数据库连接?
【解决方案2】:

最好的办法是mocha--delayed开关。摩卡医生说

如果您需要在任何套件运行之前执行异步操作(例如,动态生成测试),您可以延迟根套件。使用 --delay 标志运行 mocha。

例如,以这种方式使用 mocha mocha --recursive --exit --delay --ui tdd tests.js--delayed 使您可以通过显式调用 run() 来触发运行根套件。

const fn = async x => {
  return new Promise(resolve => {
    setTimeout(resolve, 1500, 2 * x);
  });
};

(async function() {
  const z = await fn(3);

  suite("won't run until run() executes", () => {})

  run();
})();

欲了解更多信息,请阅读https://mochajs.org/#delayed-root-suite

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
猜你喜欢
  • 1970-01-01
  • 2018-11-17
  • 2014-10-21
  • 1970-01-01
  • 2019-11-03
  • 2021-01-23
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
相关资源
最近更新 更多