hot*_*zst 22 java spring spring-boot
使用Spring Boot 2.1默认情况下禁用bean overriding,这是一件好事.
但是我确实有一些测试,我使用Mockito用模拟实例替换bean.使用默认设置,由于bean重写,具有此类配置的测试将失败.
我发现工作的唯一方法是通过应用程序属性启用bean覆盖:
spring.main.allow-bean-definition-overriding=true
Run Code Online (Sandbox Code Playgroud)
但是,我真的希望确保我的测试配置的最小bean定义设置,这将由spring指出,覆盖禁用.
我压倒的豆子要么是
我正在考虑的应该是在测试配置中覆盖bean并对其进行打击@Primary
,因为我们习惯于数据源配置.然而,这没有任何影响,让我感到疑惑:@Primary
残疾豆是否超越自相矛盾?
一些例子:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
yur*_*s87 11
spring.main.allow-bean-definition-overriding=true
可以放置在测试配置中。如果需要进行广泛的集成测试,则有时需要覆盖bean。这是不可避免的。
只是想再强调一次,即使已经提供了正确的答案,这也意味着您的bean将具有不同的名称,因此从技术上讲,这不是替代。真正的超越,如果你需要它,因为你用@Qualifiers
,@Resources
或者类似的东西,从春天启动2.X开始只能使用spring.main.allow-bean-definition-overriding=true
更新: 请注意Kotlin Bean定义DSL。在Spring Boot中,它将需要一个自定义的ApplicationContextInitializer,如下所示:
class BeansInitializer : ApplicationContextInitializer<GenericApplicationContext> {
override fun initialize(context: GenericApplicationContext) =
beans.initialize(context)
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您决定通过@Primary @Bean
方法覆盖测试中的此类基于DSL的bean中的一个,它将不会。初始化程序将在@Bean
方法之后启动,即使@Primary
在测试中,您仍然可以在测试中获得基于DSL的初始bean @Bean
。另一种选择是也为您的测试创建一个测试初始化程序,并将它们全部列在您的测试属性中,例如so(顺序很重要):
context:
initializer:
classes: com.yuranos.BeansInitializer, com.yuranos.TestBeansInitializer
Run Code Online (Sandbox Code Playgroud)
Bean Definition DSL还通过以下方式支持主要属性:
bean(isPrimary=true) {...}
Run Code Online (Sandbox Code Playgroud)
-在尝试注入bean时需要消除歧义,但是main:allow-bean-definition-overriding: true
如果采用纯DSL方式则不需要。
(春季启动2.1.3)
我使测试 bean 仅在test
配置文件中可用,并允许在测试时覆盖,如下所示:
@ActiveProfiles("test")
@SpringBootTest(properties = {"spring.main.allow-bean-definition-overriding=true"})
class FooBarApplicationTests {
@Test
void contextLoads() {}
}
Run Code Online (Sandbox Code Playgroud)
我在测试配置中嘲笑的 bean:
@Profile("test")
@Configuration
public class FooBarApplicationTestConfiguration {
@Bean
@Primary
public SomeBean someBean() {
return Mockito.mock(SomeBean.class);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
覆盖bean意味着在上下文中可能只有一个具有唯一名称或ID的bean。因此,您可以通过以下方式提供两个bean:
package com.stackoverflow.foo;
@Configuration
public class BaseConfiguration {
@Bean
@Lazy
public BService bService1() {
return new BService();
}
}
package com.stackoverflow.bar;
@Configuration
@Import({BaseConfiguration.class})
public class TestConfiguration {
@Bean
public BService bService2() {
return Mockito.mock(BService.class);
}
}
Run Code Online (Sandbox Code Playgroud)
如果添加,@Primary
则默认情况下将在以下位置注入主bean:
@Autowired
BService bService;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21611 次 |
最近记录: |