Spring 在内存数据库中使用 H2 进行测试截断所有表
Spring test with H2 in memory database truncate all tables
我是一名初级 CS 专业学生,使用 spring 从事 MVC 项目,我对 spring 还很陌生。
我在内存数据库中建立了一个H2,写了2个sql脚本;一个用于填充数据库,另一个用于将其清空。
据我所知,truncate table <table name>
和 delete from <table name>
之间的实际区别是 t运行cate table 是 ddl 因此它更快并且它还会重置自动递增的列。问题是 H2 的 t运行cate table 不会重置自动递增的列。你能指出我哪里搞砸了吗?
我正在对 运行 脚本使用 spring 的 SqlGroup 注释。
@SqlGroup({
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts =
"classpath:populate.sql"),
@Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts =
"classpath:cleanup.sql")
})
这是 cleanup.sql 应该 运行 满足每个 table。
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE `criteria`;
TRUNCATE TABLE `job_title`;
TRUNCATE TABLE `organization`;
TRUNCATE TABLE `organization_teams`;
TRUNCATE TABLE `organization_users`;
TRUNCATE TABLE `organization_job_titles`;
TRUNCATE TABLE `review`;
TRUNCATE TABLE `review_evaluation`;
TRUNCATE TABLE `team`;
TRUNCATE TABLE `team_members`;
TRUNCATE TABLE `user`;
TRUNCATE TABLE `user_criteria_list`;
SET FOREIGN_KEY_CHECKS=1;
而 populate.sql 只是在不违反完整性约束的情况下向 table 插入一堆行。
所以当我 运行 我的测试 class 时,只有第一个方法通过。剩下的我得到这样的东西:
违反参照完整性约束:"FK3MAB5XYC980PSHDJ3JJ6XNMMT: PUBLIC.ORGANIZATION_JOB_TITLES FOREIGN KEY(JOB_TITLES_ID) REFERENCES PUBLIC.JOB_TITLE(ID) (1)"; SQL声明:
插入 organization_job_titles
(organization_id, job_titles_id) 值 (1, 1)
我认为问题是由于未重置自动递增的列引起的。所以我写了一个不同的测试 class:
monAutoIncTest.java
@Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts =
"classpath:truncateTable.sql")
public class monAutoIncTest {
@Autowired
OrganizationService organizationService;
@Test
public void h2truncate_pls() throws BaseException {
organizationService.add(new Organization("Doogle"));
Organization fetched = organizationService.getByName("Doogle");
Assert.assertEquals(1, fetched.getId());
}
@Test
public void h2truncate_plz() throws BaseException {
organizationService.add(new Organization("Zoogle"));
Organization fetched = organizationService.getByName("Zoogle");
Assert.assertEquals(1, fetched.getId());
}
}
与truncateTable.sql
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE `organization`;
SET FOREIGN_KEY_CHECKS=1;
测试运行s的时候,哪个方法运行先通过,另一个给我这个
java.lang.AssertionError:
预期:1
实际:2
目前 H2 不支持该功能,但我们可以在 their roadmap
中看到此类计划
TRUNCATE should reset the identity columns as in MySQL and MS SQL
Server (and possibly other databases).
尝试将此语句与 TRUNCATE
:
组合使用
ALTER TABLE [table] ALTER COLUMN [column] RESTART WITH [initial value]
对每个 table 名称执行 SQL-script:
TRUNCATE TABLE my_table RESTART IDENTITY;
ALTER SEQUENCE my_table_id_seq RESTART WITH 1;
H2 应该是 1.4.200 或更高版本。
我是一名初级 CS 专业学生,使用 spring 从事 MVC 项目,我对 spring 还很陌生。
我在内存数据库中建立了一个H2,写了2个sql脚本;一个用于填充数据库,另一个用于将其清空。
据我所知,truncate table <table name>
和 delete from <table name>
之间的实际区别是 t运行cate table 是 ddl 因此它更快并且它还会重置自动递增的列。问题是 H2 的 t运行cate table 不会重置自动递增的列。你能指出我哪里搞砸了吗?
我正在对 运行 脚本使用 spring 的 SqlGroup 注释。
@SqlGroup({
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts =
"classpath:populate.sql"),
@Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts =
"classpath:cleanup.sql")
})
这是 cleanup.sql 应该 运行 满足每个 table。
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE `criteria`;
TRUNCATE TABLE `job_title`;
TRUNCATE TABLE `organization`;
TRUNCATE TABLE `organization_teams`;
TRUNCATE TABLE `organization_users`;
TRUNCATE TABLE `organization_job_titles`;
TRUNCATE TABLE `review`;
TRUNCATE TABLE `review_evaluation`;
TRUNCATE TABLE `team`;
TRUNCATE TABLE `team_members`;
TRUNCATE TABLE `user`;
TRUNCATE TABLE `user_criteria_list`;
SET FOREIGN_KEY_CHECKS=1;
而 populate.sql 只是在不违反完整性约束的情况下向 table 插入一堆行。
所以当我 运行 我的测试 class 时,只有第一个方法通过。剩下的我得到这样的东西:
违反参照完整性约束:"FK3MAB5XYC980PSHDJ3JJ6XNMMT: PUBLIC.ORGANIZATION_JOB_TITLES FOREIGN KEY(JOB_TITLES_ID) REFERENCES PUBLIC.JOB_TITLE(ID) (1)"; SQL声明:
插入 organization_job_titles
(organization_id, job_titles_id) 值 (1, 1)
我认为问题是由于未重置自动递增的列引起的。所以我写了一个不同的测试 class:
monAutoIncTest.java
@Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts =
"classpath:truncateTable.sql")
public class monAutoIncTest {
@Autowired
OrganizationService organizationService;
@Test
public void h2truncate_pls() throws BaseException {
organizationService.add(new Organization("Doogle"));
Organization fetched = organizationService.getByName("Doogle");
Assert.assertEquals(1, fetched.getId());
}
@Test
public void h2truncate_plz() throws BaseException {
organizationService.add(new Organization("Zoogle"));
Organization fetched = organizationService.getByName("Zoogle");
Assert.assertEquals(1, fetched.getId());
}
}
与truncateTable.sql
SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE `organization`;
SET FOREIGN_KEY_CHECKS=1;
测试运行s的时候,哪个方法运行先通过,另一个给我这个
java.lang.AssertionError: 预期:1 实际:2
目前 H2 不支持该功能,但我们可以在 their roadmap
中看到此类计划TRUNCATE should reset the identity columns as in MySQL and MS SQL Server (and possibly other databases).
尝试将此语句与 TRUNCATE
:
ALTER TABLE [table] ALTER COLUMN [column] RESTART WITH [initial value]
对每个 table 名称执行 SQL-script:
TRUNCATE TABLE my_table RESTART IDENTITY;
ALTER SEQUENCE my_table_id_seq RESTART WITH 1;
H2 应该是 1.4.200 或更高版本。