7

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

我有一个像

  • 应用程序
    • 楷模
      • 地址
      • 用户
      • 组织
    • 测试

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

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.

我该如何解决这个问题?

4

5 回答 5

14

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

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.

于 2013-02-01T11:15:58.813 回答
3

最佳解决方案(IMO):

try {
  mongoose.model('config')
} catch (_) {
  mongoose.model('config', schema)
}
于 2014-10-01T13:24:26.000 回答
1

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

于 2013-06-12T02:13:20.840 回答
0

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

try{
    var blog = mongoose.model('blog', Article);
} catch (error) {}
于 2013-09-11T11:55:40.423 回答
-1

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

在这里检查线程

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

于 2013-04-27T05:23:50.343 回答