【发布时间】: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) -> require(repository) -> constructor触发的,调用get而未调用连接。before在require之后调用。 -
您可以将代码 (
this.collection = db.get().collection('users');) 从存储库构造函数移动到新的init方法,并在测试模块中的before挂钩中调用此方法。因此,您将拥有一个全局before,并在每个测试模块中调用db.connect和before以进行 repo 初始化。