我正在爲使用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);
});