猫鼬模型测试需要模型

Posted

技术标签:

【中文标题】猫鼬模型测试需要模型【英文标题】:Mongoose model testing require models 【发布时间】:2013-01-16 16:09:52 【问题描述】:

我在测试我的猫鼬模型时遇到问题

我有一个类似的结构

应用程序 型号 地址 用户 组织结构 测试

模型用户和组织都需要知道模型地址。我的模型结构如下:

module.exports = function (mongoose, config) 

    var organizationSchema = new mongoose.Schema(

        name : 
            type : String
        ,
        addresses : 
            type : [mongoose.model('Address')]
        

    );

    var Organization = mongoose.model('Organization', organizationSchema);

    return Organization;
;

在我的普通应用程序中,我在需要用户和组织之前需要地址,一切都很好。我现在为用户和组织编写测试。为了注册地址模型,我调用require('../models/Address.js') 如果我运行一个测试,这工作正常。但是,如果我批量运行所有测试,我会收到一个错误,因为我尝试注册地址两次。

OverwriteModelError: Cannot overwrite Address model once compiled.

我该如何解决这个问题?

【问题讨论】:

我在这里回答了一个类似的问题。 ***.com/a/16248673/383217 【参考方案1】:

问题是你不能设置猫鼬模型两次。解决问题的最简单方法是利用 node.js require 函数。

Node.js 缓存对require 的所有调用,以防止您的模型初始化两次。但是你用函数包装你的模型。打开它们将解决您的问题:

var mongoose = require('mongoose');
var config = require('./config');

var organizationSchema = new mongoose.Schema(
    name : 
        type : String
    ,
    addresses : 
        type : [mongoose.model('Address')]
    
);

module.exports = mongoose.model('Organization', organizationSchema);

另一种解决方案是确保每个模型只初始化一次。例如,您可以在运行测试之前初始化所有模块:

Address = require('../models/Address.js');
User = require('../models/User.js');
Organization = require('../models/Organization.js');

// run your tests using Address, User and Organization

或者您可以在模型中添加try catch 语句来处理这种特殊情况:

module.exports = function (mongoose, config) 

    var organizationSchema = new mongoose.Schema(

        name : 
            type : String
        ,
        addresses : 
            type : [mongoose.model('Address')]
        

    );

    try 
        mongoose.model('Organization', organizationSchema);
     catch (error) 

    return mongoose.model('Organization');
;

更新:在我们的项目中,我们有 /models/index.js 文件来处理所有事情。首先,它调用mongoose.connect 建立连接。然后它需要models 目录中的每个模型并创建它的字典。所以,当我们需要一些模型(例如user)时,我们通过调用require('/models').user来获取它。

【讨论】:

我想采用第一个解决方案,但由于引用了 mongoose,我很担心,我希望这不会破坏对 mongoose 的引用,因为我在 app.js 文件中执行了 mongoose.connect,但正如您所说,节点会收集需求并在已经需要的情况下提供副本? 重构了我的代码,删除了函数包装器并且工作正常,谢谢! 是的,但在这种情况下,您应该在初始化任何模型之前调用mongoose.connect 我认为猫鼬会缓冲这些动作直到建立连接? 我需要我的模型才能连接到数据库,据我所知这是可行的【参考方案2】:

最佳解决方案 (IMO):

try 
  mongoose.model('config')
 catch (_) 
  mongoose.model('config', schema)

【讨论】:

【参考方案3】:

这个问题已经有了答案,但要以独特的方式完成这个问题,请查看https://github.com/fbeshears/register_models。此示例项目使用一个 register_models.js,其中包括来自文件名数组的所有模型。它工作得非常好,你几乎可以在任何需要它们的地方得到所有模型。请记住,node.js 的缓存会在项目运行时缓存项目中的对象。

【讨论】:

【参考方案4】:

我使用 try/catch 来解决这个问题,它工作正常。但我认为这不是最好的方法。

try
    var blog = mongoose.model('blog', Article);
 catch (error) 

【讨论】:

【参考方案5】:

我通过修补 r.js 并确保我的所有模块都使用 localRequire 调用来解决此问题。

在这里查看帖子

https://github.com/jrburke/requirejs/issues/726

【讨论】:

以上是关于猫鼬模型测试需要模型的主要内容,如果未能解决你的问题,请参考以下文章

NestJS如何在单元测试中创建新的猫鼬模型?

设计猫鼬模型

测试猫鼬预保存钩子

如何测试猫鼬预钩“保存”和bcryptjs

重置猫鼬模型缓存

单元测试:使用填充时如何模拟猫鼬代码?