使用 @RestClientTest 排除 @SpringBootApplication 类进行单元测试
Posted
技术标签:
【中文标题】使用 @RestClientTest 排除 @SpringBootApplication 类进行单元测试【英文标题】:Exclude @SpringBootApplication class for unit testing with @RestClientTest 【发布时间】:2020-06-21 08:49:45 【问题描述】:我有一个使用RestTemplate
的简单服务类。我正在使用 @RestClientTest
对其进行测试,并希望只初始化所需的服务 bean
@SpringBootApplication
class DemoApplication
@Bean fun restTemplate() = RestTemplateBuilder().build()
@Bean fun xyzService() = XyzService()
@Service
class MyServiceImpl(private val restTemplate: RestTemplate): MyService
override fun fetch(id: String)
print(restTemplate.getForObject(URI("http://localhost:9090"), String::class.java))
@RestClientTest(MyServiceImpl::class)
@AutoConfigureWebClient(registerRestTemplate = true)
class MyServiceTest
@Autowired
private lateinit var mockServer: MockRestServiceServer
@Autowired
private lateinit var myService: MyService
@Test
fun test()
mockServer.expect(ExpectedCount.once(), MockRestRequestMatchers.requestTo(URI("http://localhost:9090")))
.andExpect(MockRestRequestMatchers.method(HttpMethod.GET))
.andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body("hello world"))
myService.fetch("123")
我想在测试中排除DemoApplication
,只测试服务类的bean。问题是 xyzService
的 bean 初始化失败(它依赖于 RabbitTemplate),我不想用 mocks 搞乱测试代码。
【问题讨论】:
【参考方案1】:@RestClientTest 将无法正确过滤出在您的 @SpringBootApplication-class 中定义的组件(对于在主类上定义的 @EnableJpaRepositories 等配置注释也是如此)。将您的 bean 移动到使用 @Configuration 注释的其他类:
@SpringBootApplication
class DemoApplication
@Configuration
class BeansConfig
@Bean fun restTemplate() = RestTemplateBuilder().build()
@Bean fun xyzService() = XyzService()
根据 Spring-Boot 的文档:
如果您使用测试注释来测试更具体的片段 应用程序,您应该避免添加以下配置设置 特定于 main 方法的应用程序类的特定区域。
@SpringBootApplication 的底层组件扫描配置 定义用于确保切片的排除过滤器 预期的。如果您使用显式的 @ComponentScan 指令 你的 @SpringBootApplication-annotated 类,请注意那些 过滤器将被禁用。如果你使用切片,你应该定义 又来了。
【讨论】:
以上是关于使用 @RestClientTest 排除 @SpringBootApplication 类进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章
由于未绑定的 RestTemplate,Spring-Boot RestClientTest 无法正确自动配置 MockRestServiceServer