【发布时间】:2021-03-20 17:39:59
【问题描述】:
我有一个简单的 Spring Boot 应用程序,它使用 Spring Data JDBC 存储库并公开 REST API。除了我的集成测试外,一切似乎都运行良好。请参阅下面的存储库配置摘录。
@Configuration
@EnableJdbcRepositories
class RepositoryConfig : AbstractJdbcConfiguration() {
@Bean
@Profile("int-test")
fun intTestDataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("sql/h2/schema_create.sql")
.build()
}
@Bean
fun namedParameterJdbcOperations(dataSource: DataSource): NamedParameterJdbcOperations {
return NamedParameterJdbcTemplate(dataSource)
}
@Bean
fun transactionManager(dataSource: DataSource): TransactionManager {
return DataSourceTransactionManager(dataSource)
}
}
接下来是集成测试。
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("int-test")
@Transactional
class OrganizationControllerIntTest {
@Autowired
private lateinit var organizationRepository: OrganizationRepository
@Autowired
private lateinit var restTemplate: TestRestTemplate
@Autowired
private lateinit var testDataGenerator: TestDataGenerator
@BeforeEach
fun beforeEach() {
val organizations = testDataGenerator.organizations(10).toList()
organizationRepository.saveAll(organizations)
}
@Test
fun `When GET organizations then return all organizations`() {
val result = restTemplate.getForEntity("/organizations", String::class.java)
assertThat(result?.statusCode, equalTo(HttpStatus.OK))
assertThat(result?.body, containsString("items"))
}
}
如果没有应用@Transactional 注解,则测试成功。由于我需要在每次测试后回滚更改,因此我想让测试成为事务性的。问题是,在这种情况下,响应不包含任何项目,例如数据库将是空的,我无法弄清楚原因。
【问题讨论】:
-
如果您的测试是事务性的,则不会在测试后提交和回滚。但是,它仅在事务内部可见。当您调用一个实际端点时,该端点仅仅因为尚未提交而看不到数据。将
@Transactional与完整的集成测试一起使用是行不通的(在使用MockMvc时它会起作用,因为它不会发出实际请求并在同一个线程和事务中运行。 -
确实有道理。那么在每次集成测试之后/之前重置数据库状态的通常做法是什么?只是删除
@AfterEach方法中的所有内容?您是否考虑将您的评论转换为答案,以便我接受并提供给其他人?
标签: spring spring-boot spring-data spring-boot-test spring-data-jdbc