英文:
Alternative to @DirtyContext for isolated JUnit tests under spring boot with H2 in memory db
问题
现在我在我的JUnit测试类中使用 `@DirtiesContext(classMode=DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)`,但我认为这种方法过于过度,而且增加了比必要更多的工作量(和开销),因为整个上下文将在每个测试案例之前重新创建。我唯一需要的是`@DirtiesContext`注释,是我的内存中的H2数据库在每个测试方法之前都应该是空的并且重新创建的。有没有一种简单的方法在每个测试案例开始时自动创建一个新的空的H2数据库?
附注:我认为通过手动编写一个清空数据库的`@Before`注释方法,在应用程序随着100多个表等的增长时是不可扩展的。
当前代码示例:
__*测试类*__
```Java
@SpringBootTest
@ExtendWith(SpringExtension.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@ActiveProfiles("test")
@Slf4j
public class TestClass {
@Test
@DisplayName("检查 X 是否已保存在数据库中")
public void doXTest() {
// 进行独立的测试等等
}
@SneakyThrows
@Test
@DisplayName("执行 y")
public void doYTestMethod() {
// 进行独立的测试
}
}
application.yml
spring:
datasource:
url: jdbc:h2:mem:template-db
driver-class-name: org.h2.Driver
username: XXXXXXX
password: XXXXXXX
h2:
console:
enabled: true
path: /h2-console
jpa:
database-platform: org.hibernate.dialect.H2Dialect
<details>
<summary>英文:</summary>
Right now I'm using `@DirtiesContext(classMode=DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)` in my JUnit-Testclasses, but I think this approach is way to overkill and also does add way more workload (and overhead) than needed, since the whole context will be recreated before each test case. The only thing I need out of the Annotation `@DirtiesContext` is that my in memory H2 database should be empty and recreated before each test method. Is there an easy way to automatically start each test case with a newly created and empty h2 Database?
PS: I think doing a `@Before` annotated method that clears the db by hand is not scaleable when the application will grow with over 100+ tables etc.
Current code example:
__*Testclass*__
```Java
@SpringBootTest
@ExtendWith(SpringExtension.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@ActiveProfiles("test")
@Slf4j
public class TestClass {
@Test
@DisplayName("Check if X is saved in database")
public void doXTest() {
// do tests etc isolated
}
@SneakyThrows
@Test
@DisplayName("Do y")
public void doYTestMethod() {
// do test isolated with
}
}
application.yml
spring:
datasource:
url: jdbc:h2:mem:template-db
driver-class-name: org.h2.Driver
username: XXXXXXX
password: XXXXXXX
h2:
console:
enabled: true
path: /h2-console
jpa:
database-platform: org.hibernate.dialect.H2Dialect
答案1
得分: 3
你可以使用@Transactional
注解来标记你的测试类,这将导致每个测试在一个事务中运行,并在每个测试后回滚。这应该在每个测试后保持数据库表的干净状态,不需要为每个测试重新创建数据库(因为这也相当昂贵)。
如果你正在使用@DataJpaTest
,它已经包含了@Transactional
注解。
英文:
You can annotate your test class with @Transactional
and this will result that each test will run in a transaction that is rolled back after each test. This should leave the database tables in a clean test after each test and there shouldn't be a need to re-create the database for each test (as it's also rather expensive).
If you are using @DataJpaTest
this already comes with the @Transactional
annotation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论