【发布时间】:2019-04-07 22:02:32
【问题描述】:
默认使用Spring Boot 2.1 bean overriding is disabled,这是一件好事。
但是,我确实有一些测试,我使用 Mockito 将 bean 替换为模拟实例。使用默认设置,这种配置的测试将由于 bean 覆盖而失败。
我发现唯一可行的方法是通过应用程序属性启用 bean 覆盖:
spring.main.allow-bean-definition-overriding=true
但是我真的很想确保为我的测试配置设置最少的 bean 定义,spring 会在禁用覆盖的情况下指出这一点。
我要覆盖的 bean 要么是
- 在导入到我的测试配置中的另一个配置中定义
- 通过注解扫描自动发现 bean
我的想法应该在覆盖 bean 的测试配置中工作,并在其上添加 @Primary,就像我们习惯于数据源配置一样。然而,这没有任何效果,让我想知道:@Primary 和禁用的 bean 是否相互矛盾?
一些例子:
package com.stackoverflow.foo;
@Service
public class AService {
}
package com.stackoverflow.foo;
public class BService {
}
package com.stackoverflow.foo;
@Configuration
public BaseConfiguration {
@Bean
@Lazy
public BService bService() {
return new BService();
}
}
package com.stackoverflow.bar;
@Configuration
@Import({BaseConfiguration.class})
public class TestConfiguration {
@Bean
public BService bService() {
return Mockito.mock(BService.class);
}
}
【问题讨论】:
-
与其为您自己的配置提供模拟,不如使用
@MockBean并让Spring Boot 进行替换。所以不要在你的代码中使用@Autowired BService bService做@MockBean BService bService。节省您维护仅用于测试的配置。 -
上面 M. Deinum 的评论确实解决了这个问题,但只有当你实际使用模拟时。当你需要在测试中覆盖一个 bean 时——它没有帮助。
-
请注意,在特定测试中使用
@MockBean会导致创建新的上下文(而不是重用缓存的上下文)并导致测试运行速度变慢。
标签: java spring spring-boot