当我第二次 运行 我的测试时,为什么我在 Mongoose 中出现错误 "Cannot overwrite model once compiled"?
Why do I get error "Cannot overwrite model once compiled" in Mongoose when I run my test a second time?
我已阅读相关内容post:Cannot overwrite model once compiled Mongoose
问题是这些解决方案都没有帮助我解决问题。
我得到标题中的错误,我有以下设置:
文件夹结构:
我的模型是这样的:
forums.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = require("./topicGroups");
const forumSchema = new Schema({
title: String,
topicGroups: [topicGroupSchema]
})
const Forum = mongoose.model("forums", forumSchema);
module.exports = Forum;
topicGroups.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = new Schema({
title: String,
// Todo: add topics
})
module.exports = topicGroupSchema;
我的 test_helper 和 saveForum_test.js 文件如下所示:
saveForum_test.js
const assert = require("assert");
const Forum = require("../model/forums")
describe("Creating records", () => {
it("can save a new forum", (done) => {
const forum = new Forum({
title: "CodeHUB"
})
forum.save()
.then(() => {
assert(forum.isNew)
done();
})
})
})
test_helper.js
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
before(done => {
mongoose.connect("mongodb://myuser:mypassword@ds221339.mlab.com:21339/clicker", { useNewUrlParser: true });
mongoose.connection
.once("open", () => {done()})
.on("error", error => {
console.warn("error", error)
})
})
// FIXME: error when saved twice
beforeEach(done => {
console.log(mongoose.connection.collections.forums)
mongoose.connection.dropCollection("forums", () => {
done();
})
})
所以当我 运行 我的 mocha 测试套件时,一切都按预期工作。
但是当我更改某些内容并再次 运行 时,我收到错误
OverwriteModelError: Cannot overwrite forums
model once compiled.
我将 mlab 与猫鼬一起使用,而不是本地安装的 mongodb。也许与此有关?我想不通,我检查了所有文件和导入等 10 次,找不到错误,可以吗?
我已经解决了问题。
原来问题出在我 运行 我的测试套件上。
我在 package.json
中的 npm run test
命令执行了以下操作:
"test": "mocha --watch"
这是错误。我认为 --watch
不会重新实例化所有内容,就像 "Hot Module Replacement".
我安装了 nodemon
并像这样更改了我的测试脚本:
"test": "nodemon --exec \"mocha -R min\""
这可以确保重新运行整个文件并且不会出现错误。
另一个应该有效的相关 post:mocha --watch and mongoose models
还有另一种方法可以解决这个问题并继续使用 mocha --watch。
无需模型,您可以使用像这样的函数,这样模型就不会被覆盖。
function loadModel(modelName, modelSchema) {
return mongoose.models[modelName] // Check if the model exists
? mongoose.model(modelName) // If true, only retrieve it
: mongoose.model(modelName, modelSchema) // If false, define it
}
假设您有一个模型 'User'。您必须使用上述功能导出它:
const userSchema = {...}
module.exports = () => loadModel('User', userSchema)
现在,当您想要导入模型时,您可以调用以下函数:
const User = require('../pathToTheModelLoaderFunction/user.js')()
我建议你有一个更简单的方法,就是在测试完成后删除模型 运行。
这里是:
after(() => {
delete mongoose.connection.models['MyModelName'];
});
您也可以在所有之前添加它,以确保您在没有现有模型的情况下开始所有测试。
Object.keys(mongoose.connection.models).forEach(modelName => {
delete mongoose.connection.models[modelName]
})
我在导出模型时解决了这个问题。
return mongoose.models[modelName]
? mongoose.model(modelName)
: mongoose.model(modelName, modelSchema)
我已阅读相关内容post:Cannot overwrite model once compiled Mongoose
问题是这些解决方案都没有帮助我解决问题。
我得到标题中的错误,我有以下设置:
文件夹结构:
我的模型是这样的:
forums.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = require("./topicGroups");
const forumSchema = new Schema({
title: String,
topicGroups: [topicGroupSchema]
})
const Forum = mongoose.model("forums", forumSchema);
module.exports = Forum;
topicGroups.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const topicGroupSchema = new Schema({
title: String,
// Todo: add topics
})
module.exports = topicGroupSchema;
我的 test_helper 和 saveForum_test.js 文件如下所示:
saveForum_test.js
const assert = require("assert");
const Forum = require("../model/forums")
describe("Creating records", () => {
it("can save a new forum", (done) => {
const forum = new Forum({
title: "CodeHUB"
})
forum.save()
.then(() => {
assert(forum.isNew)
done();
})
})
})
test_helper.js
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
before(done => {
mongoose.connect("mongodb://myuser:mypassword@ds221339.mlab.com:21339/clicker", { useNewUrlParser: true });
mongoose.connection
.once("open", () => {done()})
.on("error", error => {
console.warn("error", error)
})
})
// FIXME: error when saved twice
beforeEach(done => {
console.log(mongoose.connection.collections.forums)
mongoose.connection.dropCollection("forums", () => {
done();
})
})
所以当我 运行 我的 mocha 测试套件时,一切都按预期工作。 但是当我更改某些内容并再次 运行 时,我收到错误
OverwriteModelError: Cannot overwrite
forums
model once compiled.
我将 mlab 与猫鼬一起使用,而不是本地安装的 mongodb。也许与此有关?我想不通,我检查了所有文件和导入等 10 次,找不到错误,可以吗?
我已经解决了问题。
原来问题出在我 运行 我的测试套件上。
我在 package.json
中的 npm run test
命令执行了以下操作:
"test": "mocha --watch"
这是错误。我认为 --watch
不会重新实例化所有内容,就像 "Hot Module Replacement".
我安装了 nodemon
并像这样更改了我的测试脚本:
"test": "nodemon --exec \"mocha -R min\""
这可以确保重新运行整个文件并且不会出现错误。
另一个应该有效的相关 post:mocha --watch and mongoose models
还有另一种方法可以解决这个问题并继续使用 mocha --watch。
无需模型,您可以使用像这样的函数,这样模型就不会被覆盖。
function loadModel(modelName, modelSchema) {
return mongoose.models[modelName] // Check if the model exists
? mongoose.model(modelName) // If true, only retrieve it
: mongoose.model(modelName, modelSchema) // If false, define it
}
假设您有一个模型 'User'。您必须使用上述功能导出它:
const userSchema = {...}
module.exports = () => loadModel('User', userSchema)
现在,当您想要导入模型时,您可以调用以下函数:
const User = require('../pathToTheModelLoaderFunction/user.js')()
我建议你有一个更简单的方法,就是在测试完成后删除模型 运行。
这里是:
after(() => {
delete mongoose.connection.models['MyModelName'];
});
您也可以在所有之前添加它,以确保您在没有现有模型的情况下开始所有测试。
Object.keys(mongoose.connection.models).forEach(modelName => {
delete mongoose.connection.models[modelName]
})
我在导出模型时解决了这个问题。
return mongoose.models[modelName]
? mongoose.model(modelName)
: mongoose.model(modelName, modelSchema)