使用mocha与mongodb-memory-server搭建单元测试时logWarnFn报错如何解决
问题描述
我正尝试使用mocha和mongodb-memory-server(作为内存数据库)搭建测试用例套件,具体实现如下:
项目结构

测试运行脚本(package.json配置)
"scripts": { "test": "mocha 'app/**/*.spec.js' --recursive --exit" },
全局初始化配置(global.spec.js)
用于初始化内存MongoDB:
const { MongoMemoryServer } = require("mongodb-memory-server"); const mongoose = require("mongoose"); mongoose.set("usePushEach", true); let mongoServer; before(async function () { // 首次运行时会下载mongod二进制文件 this.timeout(30 * 1000); mongoServer = new MongoMemoryServer(); const mongoUri = await mongoServer.getUri(); await mongoose.connect(mongoUri, {}); process.env.AGENDA_DB_URI = mongoUri; }); after(function () { mongoose.disconnect(); mongoServer.stop(); });
预下载配置(test-setup.js)
用于首次运行时提前触发MongoDB二进制文件下载:
const { MongoMemoryServer } = require("mongodb-memory-server"); (async function() { // 首次运行触发下载mongodb可执行文件 const mongoServer = new MongoMemoryServer(); await mongoServer.getUri(); mongoServer.stop(); })() .then(() => { process.exit(0); }) .catch(err => { console.error(err); process.exit(1); });
问题现象
所有*.spec.js测试文件都存放在modules目录下,该目录下每个子文件夹都对应一个.spec.js文件。执行npm run test命令时抛出如下错误:
1) "before all" hook 0 passing (448ms) 1 failing 1) "before all" hook: Uncaught Error: TypeError: logWarnFn is not a function
初步判断logWarnFn相关报错来自i18n依赖,正常启动服务时无此异常。
依赖版本
"mongodb-memory-server": "^6.6.2", "mocha": "^6.0.2", "i18n": "0.8.3",
解决方案
该报错核心原因是i18n@0.8.3版本在mocha测试环境下初始化时,没有正确注入默认的日志警告函数,和mongodb-memory-server无直接关联,可按以下步骤修复:
- 优先方案:升级i18n版本
i18n在0.8.4及之后的版本已经修复了日志函数未初始化的边界问题,直接将package.json中的i18n版本升级到^0.15.1(当前稳定版)后重新安装依赖即可,升级后不会影响原有功能逻辑。 - 临时兼容方案(不升级i18n)
在global.spec.js的最顶部提前初始化i18n的日志函数,添加如下代码:
const i18n = require('i18n'); i18n.configure({ // 此处复制项目正常启动时的i18n配置即可 locales: ['zh-CN', 'en'], directory: __dirname + '/locales', logWarnFn: function (msg) { console.warn('i18n warn:', msg); } });
- 额外优化建议
当前的mocha运行命令没有指定加载global.spec.js作为全局前置钩子,测试时很可能不会执行这个文件里的before/after逻辑,需要修改package.json的test脚本:
"scripts": { "test": "mocha --file app/global.spec.js 'app/**/*.spec.js' --recursive --exit" }
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

