如何解决在Spring配置中模拟命名的豆而不使用allow-bean-definition-overriding吗?
我有两个具有相同签名的bean。命名它们是为了获得正确的实例给请求它们的类。
@Configuration
public class MyConfiguration {
@Bean("durationForX")
public Duration durationForX() {
return Duration.ofSeconds(1);
}
@Bean("durationForY")
public Duration durationForY() {
return Duration.ofSeconds(5);
}
}
并用作
@Component
public class MyService {
public MyService(
@Qualifier("durationForX") duration
) {
...
}
}
和Y相似。
现在,我想在集成测试中自动装配上述bean的模型。我尝试了以下
@Configuration
@Profile("my-test-profile")
public class IntegrationTestConfiguration {
@Primary
@Bean("durationForX")
public Duration durationForXMock() {
return Duration.ofMillis(100);
}
@Primary
@Bean("durationForY")
public Duration durationForYMock() {
return Duration.ofMillis(500);
}
@Primary
@Bean
public AnotherService anotherService() {
// This one works as expected,probably because it is not a named bean
...
}
}
在运行集成测试时会导致错误消息
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'durationForX',defined in class path resource [com/../../MyConfiguration.class],could not be registered. A bean with that name has already been defined in class path resource [com/.../.../IntegrationTestConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
在集成测试中,我并不会自动装配实例本身,只有一个入口可以调用该应用程序。
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,classes = {MyApp.class})
@ActiveProfiles("it")
class MyIntegrationTest {
@Autowired
GraphQLTestTemplate graphQL;
...
}
我不太希望将bean覆盖设置为true,因为我想控制在哪里使用哪些bean。我希望模拟命名的bean遵循与未命名的bean相同的模式,这是为什么呢?有任何解决方法的想法吗?
解决方法
我建议使用其他配置文件进行测试,例如,您可以在主application.yml
中为主要应用程序定义值
application.yml
duration1:1
duration2:5
然后使用MyConfiguration
注释在@Value
类中阅读它们
@Configuration
public class MyConfiguration {
@Value("${duration1})
private Integer duration1;
@Value("${duration2})
private Integer duration2;
@Bean("durationForX")
public Duration durationForX() {
return Duration.ofSeconds(duration1);
}
@Bean("durationForY")
public Duration durationForY() {
return Duration.ofSeconds(duration2);
}
}
现在进行测试,在application-test.yml
或src/main/resources
下创建src/test/resources
,然后添加具有测试值的属性
application-test.yml
duration1:100
duration2:500
不需要任何IntegrationTestConfiguration
文件,您只需在test.yml
文件中维护测试属性
注意::请确保使用@Profile("test")
和@SpringBootTest
注释测试类以加载具有相应测试属性的测试应用程序复制上下文。
@SpringBootTest
@Profile("test)
public class AppTest {
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。