要使用sequelize as ORM在mysql数据库上执行单元测试,我需要在每个测试开始运行时刷新数据库。实际上,我写了一个这样的解决方案:
beforeEach(() => {
table1.destroy({ where: {} })
table2.destroy({ where: {} })
table3.destroy({ where: {} })
})
但每次创建表时,我都必须添加另一条指令。我将实现一条指令来执行整个模式的完全擦除
类似于:
beforeEach(() => db.clean())
2条答案
按热度按时间djp7away1#
sequelize.truncate({ cascade: true, restartIdentity: true })
记录在:https://sequelize.org/api/v6/class/src/sequelize.js~sequelize#instance-method-truncate这将截断所有表,这似乎最接近您想要的:
截断通过序列化模型定义的所有表。这是通过在每个模型上调用
Model.truncate()
来完成的。对于
option
参数:除了truncate之外,传递给
Model.destroy
的选项并行测试可以使用以下提到的技术之一进行处理:Willhttps://sqa.stackexchange.com/questions/16854/designing-database-reliant-tests-for-parallel-execution/47244#47244的mocking suggestion也解决了并行问题,因此也值得研究一下。
{truncate: cascade}
在涉及外键时是必需的,否则PostgreSQL 13.4会抱怨:{truncate: cascade}
使其运行TRUNCATE "Mytable" CASCADE
而不仅仅是TRUNCATE "MyTable"
,相关:{restartIdentity: true}
还可以通过重置主键计数器来帮助提高测试的可重复性:How to reset autoIncrement primary key with sequelize?但请注意,它在SQLite上是坏的:https://github.com/sequelize/sequelize/issues/13286最小可运行示例:
当我们运行此命令时,Sequelize会记录以下两行数据库代码:
这似乎是TRUNCATE语句的版本,根据:https://sqlite.org/lang_delete.html#the_truncate_optimization
在6.5.1,Node v14.16.0上测试。
另一种测试方法:SQLite内存数据库
对于在SQLite上进行测试,这是一个很好的方法,它可以确保每次测试都是完全干净的,您甚至不必担心截断或创建唯一的数据库名称
eblbsuwk2#
进行 * 单元测试 * 时,请勿接触数据库。
如果您正在测试与sequelize对话的业务逻辑,请创建要sequelize的接口的模拟,并将其注入到正在测试的单元中。然后,您可以针对对模拟接口的方法的调用做出Assert或期望。如果没有测试环境的更多细节,就不可能提供比这更具体的指导,但是您可以研究sequelize-mocking包来促进这一点。
如果你正在测试sequelize实际上是在和你的数据库对话,那么你所做的不仅仅是单元测试,我认为你会想要一种带外的方式来初始化和管理环境,但我也要指出,sequelize已经有了一整套测试。