mocha --watch and mongoose models

浪尽此生 提交于 2019-12-22 06:45:41

问题


If I leave mocha watching for changes, every time I save a file mongoose throws the following error:

OverwriteModelError: Cannot overwrite Client model once compiled

I know that mongoose won't allow to define a model twice, but I don't know how to make it work with mocha --watch.

// client.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var clientSchema = new Schema({
    secret: { type: String, required: true, unique: true },
    name: String,
    description: String,
    grant_types: [String],
    created_at: { type: Date, default: Date.now }
});

module.exports = mongoose.model('Client', clientSchema);

And here is the test

// client-test.js
var chai = require('chai');
var chaiHttp = require('chai-http');
var mongoose = require('mongoose');

var server = require('../../app');
var Client = require('../../auth/models').Client;

var should = chai.should();

chai.use(chaiHttp);

describe('client endpoints', function() {
    after(function(done) {
        mongoose.connection.close();
        done();
    });

    it('should get a single client on /auth/client/{clientId} GET', function(done) {
        var clt = new Client({
            name: 'my app name',
            description: 'super usefull and nice app',
            grant_types: ['password', 'refresh_token']
        });

        clt.save(function(err) {
            chai.request(server)
                .get('/auth/client/' + clt._id.toString())
                .end(function(err, res) {
                    res.should.have.status(200);
                    res.should.be.json;
                    res.body.should.have.property('client_id');
                    res.body.should.not.have.property('secret');
                    res.body.should.have.property('name');
                    res.body.should.have.property('description');
                    done();
                });
        });
    });
});

回答1:


I had the same issue. My solution was to check whether the model was created/compiled yet, and if not then do so, otherwise just retrieve the model.

using mongoose.modelNames() you can get an array of the names of your models. Then use .indexOf to check if the model you want to get is in the array or not. If it is not, then compile the model, for example: mongoose.model("User", UserSchema), but if it is already defined (as is the case with mocha --watch), simply retrieve the model (don't compile it again), which you can do with for example: mongoose.connection.model("User").

This is a function which returns a function to do this checking logic, which itself returns the model (either by compiling it or just retrieving it).

const mongoose = require("mongoose");
//returns a function which returns either a compiled model, or a precompiled model
//s is a String for the model name e.g. "User", and model is the mongoose Schema
function getModel(s, model) {
  return function() {
    return mongoose.modelNames().indexOf(s) === -1
      ? mongoose.model(s, model)
      : mongoose.connection.model(s);
  };
}
module.exports = getModel;

This means you have to require your model a bit differently, since you are likely replacing something like this:

module.exports = mongoose.model("User", UserSchema);

which returns the model itself, with this:

module.exports = getModel("User", UserSchema);

which returns a function to return the model, either by compiling it or just retrieving it. This means when you require the 'User' model, you would want to call the function returned by getModel:

const UserModel = require("./models/UserModel")();

I hope this helps.




回答2:


Here is a simpler code for the function getModel() that George is proposing

function getModel(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
}

For a larger explanation on how to define and require the model, look here

Hope this helps :)



来源:https://stackoverflow.com/questions/39035634/mocha-watch-and-mongoose-models

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