我找到了一个库:sequelize-fixtures让我分道扬but,但最终它非常不一致,偶尔会抛出约束错误:未处理的拒绝SequelizeUniqueConstraintError:验证错误,即使我没有对模型进行任何验证.
这是我如何进行测试
const sequelize = new Sequelize('test_db', 'db', null, { logging: false, host: 'localhost', port: '5432', dialect: 'postgres', protocol: 'postgres' }) describe('/auth/whoami', () => { beforeEach((done) => { Fixtures.loadFile('test/fixtures/data.json', models) .then(function(){ done() }) }) afterEach((done) => { sequelize.sync({ force: true }).then(() => { done() }) }) it('should connect to the DB', (done) => { sequelize.authenticate() .then((err) => { expect(err).toBe(undefined) done() }) }) it('should test getting a user', (done) => { models.User.findAll({ attributes: ['username'], }).then((users) => { users.forEach((user) => { console.log(user.password) }) done() }) }) })
我的模型定义如下:
var Sequelize = require('sequelize'), db = require('./../utils/db') var User = db.define('User', { username: { type: Sequelize.STRING(20), allowNull: false, notEmpty: true }, password: { type: Sequelize.STRING(60), allowNull: false, notEmpty: true } }) module.exports = User
错误日志:
Fixtures: reading file test/fixtures/data.json... Executing (default): CREATE TABLE IF NOT EXISTS "Users" ("id" SERIAL , "username" VARCHAR(20) NOT NULL, "password" VARCHAR(60) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id")); Executing (default): SELECT "id", "username", "password", "createdAt", "updatedAt" FROM "Users" AS "User" WHERE "User"."id" = 1 AND "User"."username" = 'Test User 1' AND "User"."password" = 'testpassword'; Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Users' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname; Executing (default): INSERT INTO "Users" ("id","username","password","createdAt","updatedAt") VALUES (1,'Test User 1','testpassword','2016-04-29 23:15:08.828 +00:00','2016-04-29 23:15:08.828 +00:00') RETURNING *; Unhandled rejection SequelizeUniqueConstraintError: Validation error
这工作一次,然后再也没有.对于我来说,在每次测试之前,是否有更强大的方法,从一个完全干净的DB开始,我可以填写测试数据进行操作?
This is the closest I have come to finding any kind of discussion/answer.
另外,如果有人也知道为什么我仍然得到console.logs()即使我有记录:false on,那将不胜感激.
您粘贴的错误似乎表明多次插入相同的数据,导致id列发生冲突.我希望调用sequelize.sync({force:true})会在每次运行时为你清除所有数据库表,但似乎并非如此.您可以尝试将调用移动到beforeEach挂钩,以确保运行的第一个测试也具有新的数据库.
在我正在处理的应用程序上,我们不会为每个测试重新同步数据库,而是在开始时执行一次并在测试之间截断表.我们使用如下所示的清理函数:
function cleanup() { return User.destroy({ truncate: true, cascade: true }); }
create方法执行从json fixture加载数据并将它们插入数据库的工作.
function create() { var users = require('./fixtures/user.json'); return User.bulkCreate(users); }
您可以通过省略sequelize-fixture并自行处理来简化依赖关系并提高稳定性.
另外,一个不相关的建议:Sequelize的方法返回Mocha可以原生处理的承诺,因此不需要在测试和设置/拆除代码中使用完成回调:
it('should connect to the DB', () => { return sequelize.authenticate() })
如果承诺被拒绝,测试将失败.
此外,Mocha’s docs目前建议不要使用箭头功能:
Passing arrow functions to Mocha is discouraged. Their lexical binding of the
this
value makes them unable to access the Mocha context, and statements likethis.timeout(1000);
will not work inside an arrow function.