Why do I get error “Cannot overwrite model once compiled” in Mongoose when I run my test a second time?

你说的曾经没有我的故事 提交于 2019-12-25 02:57:25

问题


I have read related post: Cannot overwrite model once compiled Mongoose

Problem is neither of these solution's helped me with my problem.

I get the error in the title and I have following setup:

Folder Structure:

My models look like this:

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;

My test_helper and saveForum_test.js files look like this:

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

So when I run my test suite with mocha, everything works as expected. But when I change something, and run it again, I get the error

OverwriteModelError: Cannot overwrite forums model once compiled.

I use mlab with mongoose and not a local installed mongodb. Maybe it has something todo with that? I can't figure it out, I checked all the files and imports etc. 10 times and can't find a mistake, can you ?


回答1:


I have solved the problem.

Turns out the problem was how I was running my test suite. My npm run test command in package.json did the following:

"test": "mocha --watch"

Here was the error. I think --watch doesn't reinstantiate everything and is just like "Hot Module Replacement".

I installed nodemon and changed my test script like this:

"test": "nodemon --exec \"mocha -R min\""

This makes sure to rerun the whole files and no error is showing up.

Another related post that should work: mocha --watch and mongoose models




回答2:


There is another option to solve this and keep using mocha --watch.

Instead of requiring the models, you can use a function like this one, so the model is no overwritten.

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
}

Imagine you have a model 'User'. You would have to export it using the above function:

const userSchema = {...}

module.exports = () => loadModel('User', userSchema)

Now, when you want to import the model, you do it calling the function:

const User = require('../pathToTheModelLoaderFunction/user.js')()



回答3:


I suggest you to have a simpler approach, which just consists in deleting the model after the test did run.

Here it is:

after(() => {
    delete mongoose.connection.models['MyModelName'];
});

You may also add it before all, in order to make sure you are starting all tests with no existing models.

Object.keys(mongoose.connection.models).forEach(modelName => {
    delete mongoose.connection.models[modelName]
})


来源:https://stackoverflow.com/questions/53463644/why-do-i-get-error-cannot-overwrite-model-once-compiled-in-mongoose-when-i-run

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!