【问题标题】:Building, seeding and destroying PostgreSQL with Sequelize for testing使用 Sequelize 构建、播种和销毁 PostgreSQL 以进行测试
【发布时间】:2016-08-25 04:18:38
【问题描述】:

我正在尝试自动为每个测试构建、播种和销毁我的数据库。我正在使用 PostgreSQL、Mocha 和 Sequelize。

我找到了一个库:sequelize-fixtures,它让我走到了那里,但最终它非常不一致,偶尔会抛出约束错误:Unhandled rejection SequelizeUniqueConstraintError: Validation error,即使我没有对模型进行任何验证。

这是我做测试的方式

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

这一次有效,然后再也没有。有没有更稳健的方法让我在每次测试之前从一个完全干净的数据库开始,让我填充测试数据以进行操作?

This is the closest I have come to finding any kind of discussion/answer.


此外,如果有人也知道为什么我仍然得到console.logs(),即使我打开了logging: false,那将不胜感激。

【问题讨论】:

  • 您的模型是如何定义的? logging false 意味着 Sequelize 不会将 SQL 打印到控制台。在您的情况下,您应该启用日志以获取有关您的问题的所有信息。
  • @denisazevedo 我已经用我的模型定义和日志更新了我的帖子。我试图禁用日志记录,但由于某种原因它仍然会生成日志,所以我仍然可以看到它们。

标签: node.js postgresql testing mocha.js sequelize.js


【解决方案1】:

您粘贴的错误似乎表明多次插入相同的数据,导致id列发生冲突。

我希望调用sequelize.sync({force: true}) 会在每次运行时为您清除所有数据库表,但情况似乎并非如此。您可以尝试将您的调用转移到 beforeEach 挂钩,以确保要运行的第一个测试也有一个新的数据库。

在我正在开发的应用程序中,我们不会为每个测试重新同步数据库,而是在开始时执行一次并在测试之间截断表。我们使用如下所示的清理函数:

function cleanup() {
    return User.destroy({ truncate: true, cascade: true });
}

create 方法负责从 json 设备加载数据并将它们插入数据库。

function create() {
    var users = require('./fixtures/user.json');
    return User.bulkCreate(users);
}

您可以通过省略sequelize-fixtures 并自己处理事情来简化依赖关系并提高稳定性。

另外,一个不相关的建议:Sequelize 的方法返回 Mocha 可以本地处理的承诺,因此无需在测试和设置/拆卸代码中使用 done 回调:

 it('should connect to the DB', () => {
   return sequelize.authenticate()
 })

如果 promise 被拒绝,测试将失败。

另外,Mocha's docs 目前建议不要使用箭头函数:

不鼓励将箭头函数传递给 Mocha。它们对 this 值的词法绑定使它们无法访问 Mocha 上下文,并且像 this.timeout(1000); 这样的语句在箭头函数中不起作用。

【讨论】:

    猜你喜欢
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多