单独测试单独文件中的Mongoose模型会导致问题(使用Mockgoose&Lab)

时间:2022-03-21 02:33:19

Whenever a Mongoose model is attempted to load after it's already loaded, an error is thrown, such as:

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

error: uncaughtException: Cannot overwrite Account model once compiled. date=Fri Feb 26 2016 10:13:40 GMT-0700 (MST), pid=19231, uid=502, gid=20, cwd=/Users/me/PhpstormProjects/project, execPath=/usr/local/Cellar/node/0.12.4/bin/node, version=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], uptime=648559 OverwriteModelError: Cannot overwrite Account model once compiled.

错误:uncaughtException:编译后无法覆盖帐户模型。 date = Fri Feb 26 2016 10:13:40 GMT-0700(MST),pid = 19231,uid = 502,gid = 20,cwd = / Users / me / PhpstormProjects / project,execPath = / usr / local / Cellar / node / 0.12.4 / bin / node,version = v5.2.0,argv = [/ usr / local / Cellar / node / 0.12.4 / bin / node,/ usr / local / Cellar / node0.12.4 / bin / lab],rss = 73306112,heapTotal = 62168096,heapUsed = 29534752,loadavg = [1.6005859375,1.84716796875,1.8701171875],uptime = 648559 OverwriteModelError:编译后无法覆盖帐户模型。

Which I'm fine with, but now that I'm writing unit tests for my models, I'm running into an issue.

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

Just some basic info about the file structure...

I have all the Mongoose models in separate files, located inside the src/models/ folder, and to load these models, one simply has to require the folder, passing a Mongoose object to it, and the src/models/index.js file will load all the models, and return an object of the models. The index.js file can be seen here (And not that its relevant, but the model names are basically the filename, without the .js)

我将所有Mongoose模型放在src / models /文件夹中的单独文件中,并且要加载这些模型,只需要文件夹,将Mongoose对象传递给它,以及src / models / index.js文件将加载所有模型,并返回模型的对象。可以在这里看到index.js文件(而不是它的相关,但模型名称基本上是文件名,没有.js)

Now the Unit tests for the models are also split up into separate files. Theres one test file for each model. And even though each unit test file focuses on a specific model, some of them use other models as well (for before/after tasks).

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

Initial Problem

I just created the 2nd unit test file, and when I execute each one independently, they work just fine. But when I execute all of them, I receive the above error, stating that I'm attempting to load the models more than once. Which since I require the ./models in each unit test case, I am loading them more than once.

我刚刚创建了第二个单元测试文件,当我独立执行每个单元时,它们工作得很好。但是当我执行所有这些操作时,我收到上述错误,声明我试图多次加载模型。因为我在每个单元测试用例中需要./models,所以我不止一次加载它们。

First Resolution Attempt

I thought that maybe I could clear all of the loaded models via after() in each separate unit test file, like so:

我想也许我可以在每个单独的单元测试文件中通过after()清除所有加载的模型,如下所示:

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

Which didn't work at all (No new errors, but the same Cannot overwrite Account model once compiled error(s) persisted)

哪个根本不起作用(没有新错误,但是一旦编译错误仍然存​​在,同样无法覆盖帐户模型)

Second Resolution Attempt (semi-successful)

Instead of the models throwing an error on the last line, when it attempts to return the Mongoose.model(), I insert some logic in the top of the model, to check if the model is loaded, and if so, return that model object:

当它试图返回Mongoose.model()时,不是模型在最后一行抛出错误,而是在模型的顶部插入一些逻辑,以检查模型是否已加载,如果是,则返回该模型宾语:

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 )
}

I'm trying that out in my models right now, and it seems to work alright, (alright meaning I don't get the errors listed above, saying I'm loading models multiple times)

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

New Problem

Now whenever the unit tests execute, I receive an error, the error displays once per a model, but its the same error:

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

$ 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

There isn't too much details to go off of in that stack trace..

在堆栈跟踪中没有太多细节。

I'm not sure if its caused by the code I added into each model, checking if it's already loaded, if it was, it would either show up when I execute a single unit test, or it would only show that Cannot set property '0' of undefined twice (Once for a successful initial model load, then twice for the next two... I would think)

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

If anyone has any input, I would very much appreciate it! Thanks

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

Updates

I tried running lab --debug to get more info, and while it doesn't show any stack traces around the errors showing up, it doubles them... which is odd. So if there was 2 when executing just lab, lab --debug shows 4

我尝试运行lab --debug来获取更多信息,虽然它没有显示出现错误的任何堆栈跟踪,但它会使它们加倍......这很奇怪。因此,如果在执行实验室时有2个,则实验室--debug显示4

Also, I use Winston to do my logging. If I change the log level to debug, which shows a lot of debug entries in the console, it doesn't show any entries around these errors... So that makes me think it may not be caused by my scripts, but rather something in the unit testing dependencies?

另外,我使用Winston进行日志记录。如果我将日志级别更改为调试,它在控制台中显示了很多调试条目,它不会显示这些错误的任何条目...所以这让我觉得它可能不是由我的脚本引起的,而是某种东西在单元测试依赖项?

The errors say they originate from the error.js file, but don't say much else. I tried to find an error.js via find . -name 'events.js', with no results.. Odd

错误说它们来自error.js文件,但不要说太多其他内容。我试图通过find找到一个error.js。 -name'events.js',没有结果..奇怪

1 个解决方案

#1


0  

I think the code you placed into each model is a hack. During the normal execution, require has "global" effect - once you import the module, it will not be imported second time.

我认为你放入每个模型的代码是一个黑客。在正常执行期间,require具有“全局”效果 - 一旦导入模块,它将不会第二次导入。

Probably this normal flow is changed during the tests, but that means that it is better to find a solution which can be locally implemented inside the tests.

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

It also looks like you have the problem similar to what is discussed in this issue - OverwriteModelError with mocha 'watch'.

它看起来像你遇到的问题类似于本期讨论的问题 - 使用mocha'watch'的OverwriteModelError。

There are some solutions to try:

有一些尝试的解决方案:

1) Create new mongoose connection each time:

1)每次创建新的mongoose连接:

var db = mongoose.createConnection()

2) Run the mocha via nodemon. This one looks puzzling for me, but still worth trying, maybe it makes each test to run completely independently. I also assume you use mocha for tests:

2)通过nodemon运行mocha。这个看起来令我感到困惑,但仍值得尝试,也许它使每个测试完全独立运行。我还假设您使用mocha进行测试:

nodemon --exec "mocha -R min" test

3) Clear mongoose models and schemes after each test:

3)每次测试后清除猫鼬模型和方案:

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

#1


0  

I think the code you placed into each model is a hack. During the normal execution, require has "global" effect - once you import the module, it will not be imported second time.

我认为你放入每个模型的代码是一个黑客。在正常执行期间,require具有“全局”效果 - 一旦导入模块,它将不会第二次导入。

Probably this normal flow is changed during the tests, but that means that it is better to find a solution which can be locally implemented inside the tests.

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

It also looks like you have the problem similar to what is discussed in this issue - OverwriteModelError with mocha 'watch'.

它看起来像你遇到的问题类似于本期讨论的问题 - 使用mocha'watch'的OverwriteModelError。

There are some solutions to try:

有一些尝试的解决方案:

1) Create new mongoose connection each time:

1)每次创建新的mongoose连接:

var db = mongoose.createConnection()

2) Run the mocha via nodemon. This one looks puzzling for me, but still worth trying, maybe it makes each test to run completely independently. I also assume you use mocha for tests:

2)通过nodemon运行mocha。这个看起来令我感到困惑,但仍值得尝试,也许它使每个测试完全独立运行。我还假设您使用mocha进行测试:

nodemon --exec "mocha -R min" test

3) Clear mongoose models and schemes after each test:

3)每次测试后清除猫鼬模型和方案:

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