I am using sequelize-test-helpers
which provides a mock sequelize connection made of sinon
spies and stubs. I have three files as follows:
//unittest.js
const {sequelize, datatypes} = require('sequelize-test-helpers');
describe('User model test', function(){
const User = require('../models').User(sequelize, dataTypes);
console.log(User.hasMany.toString()); //logs sinon spy
const models = {User, Foo: 'foo'} //shouldn't matter that foo isn't an actual model since
before(function(){
console.log(User.hasMany.toString()); //logs sinon spy
User.associate(models) //error occurs here
});
});
//models.js
function User(sequelize, dataTypes){
User = sequelize.define('user', {
name: {
type: type.STRING
}
}
User.associate = function(models){
console.log(User.hasMany.toString()); //logs the sequelize.js version of the function
User.hasMany(models.Foo); //user.hasMany called with something that's not a subclass of Sequelize.Model
}
return User;
}
module.exports = {User}
I encounter the error mentioned in the code only when also running integration tests (which require the actual sequelize.js connection). If I run the unit test in isolation I encounter no errors, but running both tests at the same time causes the error.
The declaration of User inside function User
in models.js
should be const User = //definition
. Otherwise, it creates a scoping issue which causes the function itself to be returned at the end. This makes the User model a singleton.
When the require from another file (integration test) modifies what it think is its own version of the user model, it actually modifies the user model that the unittest.js file holds as well. This was a good lesson for myself to be extra careful when reusing variable names, or avoid them altogether.