考虑下面的单元测试代码,我在预先填充的SQLite数据库中添加了一个新的Tag对象。
@Test // Line 1
public void add() {
Tag tagToAdd = new Tag("Tall");
Tag addedTag = this.tagDao.add(tagToAdd);
assertNotNull(addedTag);
assertEquals(3L, addedTag.getId()); // Line 6
assertEquals(tagToAdd.getTag(), addedTag.getTag());
List<Tag> tags = this.tagDao.get();
assertEquals(3, tags.size());
}
在第6行,我期望标签的ID为3,因为该字段是AUTOINCREMENT,并且测试是用已经包含2个标签的数据库初始化的。每次我运行测试时都可以正常工作,ID总是3。
现在,我正在将flyway集成到项目中。每次运行测试时,AUTOINCREMENT都从上次运行的值开始,因此每次运行标记ID都增加1,并且测试失败。
任何想法我怎么能得到flyway总是重置数据库到一个全新的状态,并重置AUTOINCREMENT值?我可以写一个查询来手动完成,但这是不可维护的。
我已经尝试了什么?
- 集成@FlywayTest,因为这执行flyway任务清洁
- 定义了一个FlywayMigrationStrategy bean,它包含flyway.clean()
- spring.flyway设置。在我的应用程序中,验证错误清除为true。属性(也就是说,我的sql没有变化,所以不确定这是否改变了什么)
——编辑我的第一个迁移脚本包含以下内容:
DROP TABLE IF EXISTS Tag;
CREATE TABLE Tag(
id INTEGER PRIMARY KEY AUTOINCREMENT,
tag VARCHAR(255) NOT NULL UNIQUE,
createdDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modifiedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
如果我理解正确的话——你有一个数据库,在这个数据库中有一个表,这个表创建一次,每次测试都使用同一个表——当测试完成时(或在开始下一个测试之前),你只需要从表中删除行(不删除它),flyway每次运行测试时只需要在这个表中插入两个标签。
如果这是正确的-你可以在SQLite中重置序列,将其设置回1
,这样下一个插入的行将插入这个id
。您可以通过运行以下查询来实现:
UPDATE `sqlite_sequence` SET `seq` = 1 WHERE `name` = 'tags_table_name';
或者,你可以设置seq
为0
-这个值是不正确的,所以SQLite将使用下一个可用的正确值(如果表中没有行-它将是一个,如果有一些值-它将第一个可用的数字)。
另一种可能性是在测试后删除表并在运行下一个测试之前重新创建它-因为它是一个仅用于测试的数据库和表-它应该正常工作。这样,每次都可以将序列计数器设置回值1。我实际上会这样做,直到你有很好的理由不删除这个表。