擦除模式中的所有表 - sequelize nodejs

时间:2017-12-14 14:49:34

标签: javascript mysql sql node.js

要使用sequelize作为ORM对mysql数据库执行单元测试,我需要在每个测试开始运行时刷新我的数据库。 实际上我写了这样一个解决方案:

beforeEach(() => {
   table1.destroy({ where: {} })
   table2.destroy({ where: {} })
   table3.destroy({ where: {} })
})

但每次创建表时我都要添加另一条指令。 我将实现一条指令来执行整个模式的完整擦除

类似的东西:

beforeEach(() => db.clean())

2 个答案:

答案 0 :(得分:2)

进行单元测试时,不应触摸数据库。

如果您正在测试与续集相关的业务逻辑,请创建一个模拟接口以进行续集并将其注入正在测试的单元中。然后,您可以对调用mock接口的方法进行断言或期望。如果没有测试环境的更多细节,那么提供更具体的方向是不可能的,但您可以调查sequelize-mocking包来促进这一点。

如果您正在测试sequelize实际上正在与您的数据库交谈,那么您所做的远不止是单元测试,我认为您需要一种带外初始化和管理方式环境,但我也指出,sequelize已经有一整套测试。

答案 1 :(得分:1)

sequelize.truncate()

这记录在:https://sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-method-truncate 这会截断所有表,这似乎最接近您想要的:

<块引用>

截断所有通过 sequelize 模型定义的表。这是通过在每个模型上调用 Model.truncate() 来完成的。

然后可以使用以下技术之一处理并行测试:https://sqa.stackexchange.com/questions/16854/designing-database-reliant-tests-for-parallel-execution/47244#47244 Will 的 mocking suggestion 也解决了并行问题,因此也可能值得研究。

最小可运行示例:

const assert = require('assert');
const { Sequelize, DataTypes } = require('sequelize');

const sequelize = new Sequelize({
  dialect: 'sqlite',
  storage: 'db.sqlite',
});
const IntegerNames = sequelize.define(
  'IntegerNames', {
  value: { type: DataTypes.INTEGER, allowNull: false },
  name: { type: DataTypes.STRING, },
});
const IntegerNames2 = sequelize.define(
  'IntegerNames2', {
  value: { type: DataTypes.INTEGER, allowNull: false },
  name: { type: DataTypes.STRING, },
});

(async () => {
// Create and populate databases.
await IntegerNames.sync({force: true})
await IntegerNames.create({value: 2, name: 'two'});
await IntegerNames.create({value: 3, name: 'three'});
await IntegerNames2.sync({force: true})
await IntegerNames2.create({value: 4, name: 'four'});
await IntegerNames2.create({value: 5, name: 'five'});

// Check that they were populated.
assert((await IntegerNames.findAll()).length === 2);
assert((await IntegerNames2.findAll()).length === 2);

// Truncate them and check that they are empty.
await sequelize.truncate();
assert((await IntegerNames.findAll()).length === 0);
assert((await IntegerNames2.findAll()).length === 0);

// Cleanup.
await sequelize.close();
})();

当我们运行它时,Sequelize 会记录以下两个数据库行:

Executing (default): DELETE FROM `IntegerNames2s`
Executing (default): DELETE FROM `IntegerNames`

这似乎是它的 TRUNCATE 语句版本,根据:https://sqlite.org/lang_delete.html#the_truncate_optimization

在 6.5.1、Node v14.16.0 上测试。

另一种测试方法:SQLite 内存数据库

对于在 SQLite 上进行测试,这是一个很好的方法,可以确保每次都完全干净,您甚至不必担心截断或创建唯一的数据库名称

new Sequelize({
  dialect: 'sqlite',
  storage: ':memory:',
})