我正在为使用Sequelize的节点服务器编写单元测试。在一些假的数据插入我收到错误不应该存在的验证错误应该不存在的属性
SequelizeValidationError: notNull Violation: QuestionId cannot be null
注意的情况:资本Q上QuestionId
单元测试:
describe('answerQuestion',() => {
it('should insert an answer and get the next question', (done) => {
Survey.DBModel.create({lookType: 0}, {logging: false}).then(() => {
Question.DBModel.create({type: 0, text: 'Test question'}, {logging: false}).then(q1 => {
Question.DBModel.create({type: 1, text: 'Next question'}, {logging: false}).then(q2 => {
console.log('before');
QuestionOption.DBModel.create({text: 'Test option', questionId: 1, nextQuestionId: 2}, {logging: false}).then(() => {
console.log('after');
Survey.answerQuestion(1, 1, 1).then(question => {
question.should.have.property('id');
}, done);
}, done);
}, done);
}, done);
}, done);
});
});
“前”控制台输出,但错误在它之后到达'之后'
question.js
个'use strict';
module.exports = function(sequelize, DataTypes) {
var Question = sequelize.define('Question', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
type: {
allowNull: false,
type: DataTypes.INTEGER
},
text: {
allowNull: false,
type: DataTypes.STRING
},
nextQuestionId: {
type: DataTypes.INTEGER
}
}, {
classMethods: {
associate: function(models) {
models.Question.belongsTo(models.Question, {as: 'nextQuestion', foreignKey: {field: 'nextQuestionId', allowNull: true}});
models.Question.hasMany(models.Answer, {as: 'answers', foreignKey: {field: 'questionId', allowNull: false}});
models.Question.hasMany(models.QuestionOption, {as: 'options', foreignKey: {field: 'questionId', allowNull: false}});
models.Question.hasMany(models.QuestionOption, {as: 'referrers', foreignKey: {field: 'nextQuestionId', allowNull: true}});
}
}
});
return Question;
};
questionoption.js
'use strict';
module.exports = function(sequelize, DataTypes) {
var QuestionOption = sequelize.define('QuestionOption', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
questionId: {
allowNull: false,
type: DataTypes.INTEGER
},
text: {
allowNull: false,
type: DataTypes.STRING
},
nextQuestionId: {
type: DataTypes.INTEGER
}
}, {
classMethods: {
associate: function(models) {
models.QuestionOption.belongsTo(models.Question, {as: 'question', foreignKey: {field: 'questionId', allowNull: false}});
models.QuestionOption.belongsTo(models.Question, {as: 'nextQuestion', foreignKey: {field: 'nextQuestionId', allowNull: true}});
}
}
});
return QuestionOption;
};
这些模型是非常紧密耦合在一起,并有自我指涉的连接和所有其他种类的混乱。我觉得所有其他模型都与此无关,但可以根据需要提供。
在SQLite数据库上直接执行SQL,与上面的create语句具有相同的顺序和相同的属性不会引发异常,并且通过大量测试,很明显Sequelize不会尝试运行create语句QuestionOption
。它在生成要运行的SQL之前发生错误。
一些奇怪的行为是有关联模型中定义的精心和他们都有一个小写q
对它们的定义questionId
。所有关联都有一个反向关联定义,所以Sequelize不应该试图为属性创建名称。
在每次测试(成功)之前删除并重新创建所有表。
添加到的证据表明,一些奇怪的事情是,如果我从QuestionOption创建语句删除questionId: 1
,那么误差变得
SequelizeValidationError: notNull Violation: questionId cannot be null,
notNull Violation: QuestionId cannot be null
注意两者的外壳,一个较低(在一个我删除),一个是上层。
下一页疑是nextQuestionId
关联,但它已经在模型中定义,每个关联方为allowNull: true
和我在创建语句,只要它。
我完全对这种行为感到困惑,并质疑这是否是一个后续错误,尽管我需要在错误地报告之前确认这一点。
其他信息,也许可能是有用的是:
- 测试使用的是命令
NODE_ENV=test mocha
- 数据库创建用于测试的自动使用
sync
(下面的代码) - 其他所有测试都通过了运行,但这是测试中唯一使用QuestionOption的人。
- 我试图测试“生产”的作品
- 数据库模式已经证实了SQLite的GUI和所有列是适当的(没有
QuestionId
领域中的任何表(在开发中与所连接的客户端在本地运行)的方法资本Q)
数据库创建用于测试
beforeEach((done) => {
Survey.DBModel.sync({force: true, logging: false}).then(() => {
Question.DBModel.sync({force: true, logging: false}).then(() => {
Answer.DBModel.sync({force: true, logging: false}).then(() => {
QuestionOption.DBModel.sync({force: true, logging: false}).then(() => {
done();
}, done);
}, done);
}, done);
}, done);
});