-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mongoose model overwrite error #27
Comments
Mhmm interesting. I think this could be solved if you stored the rewired module under var myModel = rewire("./myModel");
require.cache[require.resolve("./myModel")] = myModel;
// than somewhere else
var myModel = require("./myModel"); // returns the rewired module It's important that rewire is the first one that executes the module since rewire always creates a fresh instance. node's require always looks up the |
Hi, I've been trying this (I work with @csugden) and I'm getting undefined for the result of myModel. Specifically:
|
As a follow-up, I noted that the object structure of what is put in the require cache by require is a bit different to what is put there by overwriting the cache. For example, modules in the cache that require has put there have a "paths" property. |
Oh yes, you're right. var myModel = rewire('./lib/myModel');
require.cache[require.resolve('./lib/myModel')] = {
exports: myModel
}; ... thus faking the actual But that's surely not a clean solution. Maybe rewire should provide a method to directly store the rewired module in the var myModel = rewire.global("./lib/myModel");
require("./lib/myModel") === myModel; // true
rewire("./lib/myModel") === myModel; // false But what happens when the Maybe there's also another solution? Any suggestions? |
The quickfix you suggested worked. Jasmine-node seems to collect the spec files together alphabetically, so I've got "aFixSpec.js" that gets loaded first. I also wanted to be able to run the tests independently, which meant keeping the use of rewire in the spec files. I got around this by using the same technique to overwrite require's cache of rewire and replace it with require (also in aFixSpec.js):
This means when you run all the tests at once, any further use of rewire outside of aFixSpec.js uses require and hence goes through the same cache, which looks like a noop; but as I mentioned above, this allows the rewire method to remain in the test specs so they can be run independently. |
Mhmm I don't get this fix ^^. If a test uses Another solution which came in my mind is to separate the registering-part from the definition. So instead of writing: var Cat = mongoose.model('Cat', { name: String }); you would write // CatSchema.js
module.exports = mongoose.Schema({
name: String
}); // Cat.js
module.exports = mongoose.model('Cat', CatSchema); I don't know what exactly you're trying to test and mock with rewire, but separating these two things is a good idea anyway. |
Close? |
ok! |
For future googlers, you could also try using sinon to enable rewire usage with mongoose models. Here is an example that worked for me: function disableNewModelDefinitions() {
var originalModel = mongoose.model;
sinon.stub(mongoose, 'model', allowModelRetrieval);
function allowModelRetrieval() {
if (arguments.length === 1) {
return originalModel.apply(mongoose, arguments);
}
}
} |
Nice 👍 |
@Trindaz Could you provide an example of how you actually use that function? Thanks! |
I believe this would work in most scenarios where you need to re-register a mongoose model: delete mongoose.connection.models['Cat'];
// proceed with rewire, proxyquire, etc. |
I've used rewire with a Mongoose model in a jasmine spec, and also used require to load the same model in a different spec. I get this error:
It looks like it's asking Mongoose to define the same model twice, whereas if we used require both times this does not happen.
Is there a workaround?
Thanks.
The text was updated successfully, but these errors were encountered: