I have a problem testing my mongoose models
I have a structure like
Both models User and Organization need to know the model Address. My models are structured like:
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;
};
In my normal app i require Address before requiring User and Organization and everything is fine. I now wrote tests for User and Organization. In order to have the Address model registered i call require('../models/Address.js')
This works fine if i run one test. But if i run all tests in a batch i get an error because i tried to register Address twice.
OverwriteModelError: Cannot overwrite Address model once compiled.
How do i solve this problem?
The problem is that you cant set mongoose model twice. The easiest way to solve your problem is to take advantage of node.js require
function.
Node.js caches all calls to require
to prevent your model from initializing twice. But you wrapping your models with functions. Unwrapping them will solve your problem:
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);
Alternative solution is to make sure that each model initialized only once. For example, you can initialize all you modules before running your tests:
Address = require('../models/Address.js');
User = require('../models/User.js');
Organization = require('../models/Organization.js');
// run your tests using Address, User and Organization
Or you can add try catch
statement to your models to handle this special case:
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');
};
Update: In our project we have /models/index.js
file to handle everything. First, it calls mongoose.connect
to establish connection. Then it requires every model in models
directory and creates a dictionary of it. So, when we need some model (e.g. user
) we requires it by calling require('/models').user
.
Best solution (IMO):
try {
mongoose.model('config')
} catch (_) {
mongoose.model('config', schema)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With