mun*_*ger 6 java testing kotlin spring-boot spring-boot-test
我有一个SpringBootTest测试应该依赖一个单独的类来设置嵌入式 Postgres 和数据源。
因此 Repository 配置如下所示:
package com.stream.repository.configuration
@Configuration
@ComponentScan(basePackages = arrayOf("com.stream.repository"))
@EntityScan(basePackages = arrayOf("com.stream.repository"))
@EnableJpaRepositories(basePackages = arrayOf("com.stream.repository"))
@EnableAutoConfiguration
class RepositoryConfiguration {
Run Code Online (Sandbox Code Playgroud)
测试类如下所示:
package com.stream.webapp.rest
@AutoConfigureMockMvc(addFilters = false)
@SpringBootTest(properties =
[
"spring.jpa.hibernate.ddl-auto=validate",
"spring.jpa.show-sql=true",
"spring.liquibase.enabled=true",
"spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.yml",
"spring.jpa.properties.hibernate.jdbc.time_zone=UTC"
],
classes = [RepositoryConfiguration::class, AuditController::class],
webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class AuditControllerTest {
Run Code Online (Sandbox Code Playgroud)
这就是它变得奇怪的地方。如果我使用该配置运行,它会抱怨找不到EntityManagerFactory
AuditService 需要一个无法找到的类型为“javax.persistence.EntityManagerFactory”的 bean。
经过一番折腾,我找到了解决这个问题的办法。如果我移动它RepositoryConfiguration以便它在包中com.stream.webapp.rest,即与AuditControllerTest它一样神奇地工作。
我似乎找不到任何理由说明为什么会这样。那么任何人都可以解释它并且有办法解决它吗?因为我不想动它。把它放在哪里很有意义。
作为旁注,它是用 Kotlin 编写的,但我不明白为什么在这种情况下它很重要。而这仅用于测试。在测试范围之外运行应用程序时,它可以工作
我还可以补充一点,AuditControllerTest它在一个模块中,RepositoryConfiguration在另一个模块中。如果将其放置在“正确”的包中(仍然是单独的模块),则不确定它是否相关,因为它可以工作
问题的 TL; DR:为什么 spring 关心 与RepositoryConfiguration位于同一个包中AuditControllerTest?
更新:这是当前配置:(RepositoryConfiguration不变
@AutoConfigureMockMvc(addFilters = false)
@ComponentScan("com.stream.repository")
@Configuration
@SpringBootTest(properties =
[
"spring.jpa.hibernate.ddl-auto=validate",
"spring.jpa.show-sql=true",
"spring.liquibase.enabled=true",
"spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.yml",
"spring.jpa.properties.hibernate.jdbc.time_zone=UTC",
"database.dbname=stream_mapper"
],
classes = [com.stream.repository.configuration.RepositoryConfiguration::class, ExceptionMapper::class, AuditController::class],
webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class AuditControllerTest {
Run Code Online (Sandbox Code Playgroud)
Spring 对此很奇怪,并且期望测试和主项目的包层次结构相等或大致相等。这样做是最佳实践,并且会为您省去很多麻烦。
为了配置集成测试,请将“BaseIntegrationTest.java”或“AbstractIntegrationTest.java”之类的内容放在与主 Spring Boot 配置相同的包层次结构中,并用“test”替换“main”。
前任:
主要配置在这里:
src/main/java/com/stream/repository/configuration/RepositoryConfiguration.java
Run Code Online (Sandbox Code Playgroud)
测试配置将在这里(使用@SpringBootTest)
src/test/java/com/stream/repository/configuration/TestRepositoryConfiguration.java
Run Code Online (Sandbox Code Playgroud)
在上面的结构中,您将大部分(或全部)Spring Boot 测试配置注释放在基本测试配置类 (TestRepositoryConfiguration.java) 上
然后您的实际测试将扩展此类:
前任:
src/test/java/com/stream/webapp/rest/AuditControllerTest.java
Run Code Online (Sandbox Code Playgroud)
将从以下开始:
class AuditControllerTest extends TestRepositoryConfiguration { ... }
Run Code Online (Sandbox Code Playgroud)
此外,您发布的主 RepositoryConfiguration.java 类有一些奇怪的事情 - 因为它具有通用的 @EnableAutoConfiguration 注释,这在特定于存储库的配置上不应该是必需的 - 它会自动包含在 @SpringBootApplication 注释中你的基础网络应用程序。
关于您的集成测试,
理想情况下, @SpringBootTest 不应在此文件中,尽管大多数指南为了简单起见将该注释放在其示例类上。理想情况下,您需要将其放在基本集成测试文件(通常是抽象的)中,该文件与定义 @SpringBootApplication 的主应用程序的基本配置文件具有相同的结构(除了测试而不是 main) - 并保持层次结构测试配置和主配置类的继承类似。
这是一篇关于优化集成测试的精彩文章 - IE 为同一类型的所有测试保持运行应用程序的一个实例。
https://www.baeldung.com/spring-tests
另外,如果您只需要测试存储库,请考虑使用@JdbcTest。如果您想从主集成测试中抽象特定于存储库的测试,则可以将其保留为单独的上下文/类型的测试,该测试不会从主应用程序测试中扩展。
显然,我无法访问您的整个代码库,因此我提出的任何建议都很难完全解决任何问题,但希望这会让您沿着正确的路线思考在结构上设置集成测试,以避免许多奇怪的构建错误和解决问题。(以及以后必须继承您的代码的每个开发人员)...
欢迎评论/提问。
| 归档时间: |
|
| 查看次数: |
277 次 |
| 最近记录: |