英文:
How to cleanup h2 db after each junit test?
问题
@BeforeEach注释之前,我正在创建junit测试,该测试在每个测试用例之前添加一些用户。 代码如下:
@BeforeEach
void setUp() {
saveUser();
saveEntry();
}
@Test
void saveUser() {
User user = new User();
user.setUserId(null);
user.setUsername("John");
user.setEmail("john@foo.com");
user.setPassword("password");
userService.saveUser(user);
}
@Test
void saveEntry() {
Entry entry = new Entry();
entry.setText("test text");
entry.setUserId(1L);
entryService.saveEntry(entry);
}
如您所见,我正在使用我的服务层中拥有的方法来创建条目和用户。 如果我逐个运行测试,就没有问题。 但是当我运行所有测试时,数据库不返回1个项目,而是返回多个项目,因此会发生异常。
我需要在每个测试之后使用@AfterEach注释清理h2数据库,但我在我的代码中没有删除方法来调用。 如何清理H2数据库?
英文:
I am making junit tests which adds some users before each test case. The code is:
@BeforeEach
void setUp() {
saveUser();
saveEntry();
}
@Test
void saveUser() {
User user = new User();
user.setUserId(null);
user.setUsername("John");
user.setEmail("john@foo.com");
user.setPassword("password");
userService.saveUser(user);
}
@Test
void saveEntry() {
Entry entry = new Entry();
entry.setText("test text");
entry.setUserId(1L);
entryService.saveEntry(entry);
}
As you see I am using the methods that I have in my service layer to create entries and users. If I run the tests one by one there is no problem. But when I run all tests then db is not returning 1 item and returning multiple items so exception occurs.
I need to cleanup h2 db after each test with maybe @AfterEach annotation but I do not have and delete method in my code to invoke. How can I cleanup the H2 db ?
答案1
得分: 5
除了@J Asgarov的回答是正确的,前提是您要使用spring-boot
,如果您想在每个测试之前和之后执行一些操作(更具体地说,在@Before
之前和@After
之后的方法之前),您可以使用@Sql
注解来执行特定的sql
脚本,例如来自测试资源的脚本。
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public class TestClass {
}
这对于sequences
可能很方便,因为它们不关心回滚。
关于@Mark Bramnik提到的@Transactional
,请小心,因为事务跨越整个测试方法,因此您无法验证事务边界的正确性。
英文:
In addition to @J Asgarov answer which is correct providing you use spring-boot
if you want to perform some actions before and after each test (more specifically before @Before
and after @After
methods) you can use @Sql
annotation to execute specific sql
script for example from test resources.
@Sql("init.sql")
@Sql(scripts = "clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public class TestClass
}
It might be handy for sequences
, since they don't care of rollback.
Regarding @Transactional
mentioned by @Mark Bramnik be careful, because the transaction spans for entire test method, so you cannot verify correctness of the transaction boundaries.
答案2
得分: 0
你提到了Spring,看起来你正在测试DAO层,所以我假设如果你在使用JUnit 4,测试是在SpringExtension/SpringRunner下运行的。
在这种情况下,
你尝试过在测试方法上使用@Transactional
吗?或者如果所有测试方法都是"transactional",你可以在测试类上放置一次。
这是如何工作的:
如果一切配置正确,Spring将在测试开始之前打开一个事务,并在测试结束后回滚该事务。
回滚应该会自动清除插入的数据。
快速搜索发现了这个教程,当然还有许多其他教程。
英文:
You've mentioned spring and it looks like you're testing DAO layer, so I assume the tests are running with SpringExtension/SpringRunner if you're on junit 4.
In this case,
Have you tried to use @Transactional
on the test method? Or alternatively if all the test methods are "transactional" you can place it once on a test class.
This works as follows:
If everything is configured correctly spring will open a transaction before the test starts, and will rollback that transaction after the test ends.
The rollback is supposed to clean the inserted data automatically.
Quick googling revealed this tutorial, surely there are many others
答案3
得分: 0
@JpaDataTest
注解测试类时,默认会回滚每个测试。
https://www.baeldung.com/spring-jpa-test-in-memory-database
英文:
@JpaDataTest
annotating the test class will rollback every test by default
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论