在单独的文件中对 Mongoose 模型进行单元测试会导致问题(使用 Mockgoose 和 Lab)

问题描述 投票:0回答:1

每当 Mongoose 模型在加载后尝试加载时,都会抛出错误,例如:

错误:uncaughtException:编译后无法覆盖

Account
模型。日期 = 2016 年 2 月 26 日星期五 10:13:40 GMT-0700 (MST),pid=19231,uid=502,gid=20,cwd=/Users/me/PhpstormProjects/project,execPath=/usr/local/Cellar/节点/0.12.4/bin/node,版本=v5.2.0,argv=[/usr/local/Cellar/node/0.12.4/bin/node,/usr/local/Cellar/node/0.12.4/bin /lab],rss = 73306112,heapTotal = 62168096,heapUsed = 29534752,loadavg = [1.6005859375,1.84716796875,1.8701171875],正常运行时间= 648559 OverwriteModelError:编译后无法覆盖
Account
模型。

我对此很满意,但现在我正在为我的模型编写单元测试,我遇到了一个问题。

只是有关文件结构的一些基本信息...

我将所有 Mongoose 模型放在单独的文件中,位于

src/models/
文件夹内,要加载这些模型,只需需要该文件夹,向其传递一个
Mongoose
对象,然后
src/models/index.js
文件就会加载所有模型,并返回模型的对象。
index.js
文件可以在here看到(并不是说它相关,但模型名称基本上是文件名,没有.js

现在模型的单元测试也分为单独的文件。每个模型都有一个测试文件。尽管每个单元测试文件都专注于特定模型,但其中一些也使用其他模型(用于之前/之后的任务)。

最初的问题

我刚刚创建了第二个单元测试文件,当我独立执行每个文件时,它们工作得很好。但是,当我执行所有这些操作时,我收到上述错误,指出我正在尝试多次加载模型。由于我在每个单元测试用例中都需要

./models
,所以我am多次加载它们。

第一次解决尝试

我想也许我可以通过每个单独的单元测试文件中的

after()
清除所有加载的模型,如下所示:

after(function(done) {
    mongoose.connection.close(function() {
        mongoose.connection.models = {}
        done()
    })
})

这根本不起作用(没有新错误,但相同编译后无法覆盖

Account
模型错误仍然存在)

第二次解决尝试(半成功)

当模型尝试返回

Mongoose.model()
时,我不会在最后一行抛出错误,而是在模型顶部插入一些逻辑,以检查模型是否已加载,如果是,则返回 that模型对象:

const thisFile  = path.basename( __filename ).match( /(.*)\.js$/ )[ 1 ]
const modelName = _.chain( thisFile ).toLower().upperFirst().value()

module.exports = Mongoose => {
    // Return this model, if it already exists
    if( ! _.isUndefined( Mongoose.models[ modelName ] ) )
        return Mongoose.models[ modelName ]

    const Schema = Mongoose.Schema

    const appSchema = new Schema( /* ..schema.. */)

    return Mongoose.model( modelName, appSchema )
}

我现在正在我的模型中尝试,它似乎工作正常,(好吧意味着我没有收到上面列出的错误,说我正在多次加载模型)

新问题

现在,每当执行单元测试时,我都会收到一个错误,该错误每个模型显示一次,但它是相同的错误:

$ lab

  ..................................................
  ...

Test script errors:

Cannot set property '0' of undefined
      at emitOne (events.js:83:20)
      at EventEmitter.emit (events.js:170:7)
      at EventEmitter.g (events.js:261:16)
      at emitNone (events.js:68:13)
      at EventEmitter.emit (events.js:167:7)

Cannot set property '0' of undefined
      at emitOne (events.js:83:20)
      at EventEmitter.emit (events.js:170:7)
      at EventEmitter.g (events.js:261:16)
      at emitNone (events.js:68:13)
      at EventEmitter.emit (events.js:167:7)

Cannot set property '0' of undefined
      at emitOne (events.js:83:20)
      at EventEmitter.emit (events.js:170:7)
      at EventEmitter.g (events.js:261:16)
      at emitNone (events.js:68:13)
      at EventEmitter.emit (events.js:167:7)

There were 3 test script error(s).

53 tests complete
Test duration: 1028 ms
No global variable leaks detected

堆栈跟踪中没有太多细节可忽略..

我不确定它是否是由我添加到每个模型中的代码引起的,检查它是否已经加载,如果是,它要么在我执行单个单元测试时显示,要么只显示无法设置未定义的属性“0”两次(一次用于成功的初始模型加载,然后两次用于接下来的两个......我认为)

如果有人有任何意见,我将非常感激!谢谢

更新

我尝试运行

lab --debug
来获取更多信息,虽然它没有显示出现的错误周围的任何堆栈跟踪,但它使错误加倍......这很奇怪。因此,如果仅执行
lab
时有 2,则
lab --debug
显示 4

此外,我使用 Winston 进行日志记录。如果我将日志级别更改为调试,这会在控制台中显示大量调试条目,但不会显示这些错误周围的任何条目...所以这让我认为这可能不是由我的脚本引起的,但是而是单元测试依赖项中的某些内容? 这些错误表明它们源自

error.js

文件,但没有多说。我试图通过find . -name 'events.js'找到error.js,但没有结果..奇怪

    

node.js unit-testing mongoose mocking hapi.js-lab
1个回答
0
投票
require

具有“全局”作用 - 一旦导入该模块,就不会再导入第二次。


可能这个正常流程在测试期间会发生变化,但这意味着最好找到一个可以在测试中本地实现的解决方案。

看起来您也遇到了与本期讨论的问题类似的问题 -

OverwriteModelError with mocha 'watch'

有一些解决方案可以尝试:

1)每次创建新的猫鼬连接:

var db = mongoose.createConnection()

2)通过nodemon运行mocha。这对我来说看起来令人费解,但仍然值得尝试,也许它使每个测试完全独立运行。我还假设您使用摩卡进行测试:

nodemon --exec "mocha -R min" test

3)每次测试后明确mongoose模型和方案:

after(function(done){ mongoose.models = {}; mongoose.modelSchemas = {}; mongoose.connection.close(); done(); });

© www.soinside.com 2019 - 2024. All rights reserved.