我在用@Configuration修饰的类中定义了Bean
:
@Configuration
public class MyBeanConfig {
@Bean
public String configPath() {
return "../production/environment/path";
}
}
我有一个用@TestConfiguration修饰的类,它应该覆盖这个Bean
:
@TestConfiguration
public class MyTestConfiguration {
@Bean
@Primary
public String configPath() {
return "/test/environment/path";
}
}
configPath
bean用于设置外部文件的路径,该文件包含必须在启动期间读取的注册码。它用在@Component类中:
@Component
public class MyParsingComponent {
private String CONFIG_PATH;
@Autowired
public void setCONFIG_PATH(String configPath) {
this.CONFIG_PATH = configPath;
}
}
在尝试调试时,我在每个方法中设置了一个断点以及测试配置类的构造函数。 @TestConfiguration
的构造函数断点被命中,所以我知道我的测试配置类是实例化的,但是该类的configPath()
方法永远不会被命中。相反,正常的@Configuration类的configPath()
方法被命中,而@Autowired
中的String
MyParsingComponent
始终为../production/environment/path
而不是预期的/test/environment/path
}。
不确定为什么会这样。任何想法都将不胜感激。
答案 0 :(得分:26)
如Spring Boot参考手册的Detecting Test Configuration部分所述,在注释为@TestConfiguration
的顶级类中配置的任何bean都将 通过组件扫描获取。所以你必须明确注册你的@TestConfiguration
课程。
您可以通过测试类的@Import(MyTestConfiguration.class)
或@ContextConfiguration(classes = MyTestConfiguration.class)
来完成此操作。
另一方面,如果您的@TestConfiguration
注释的类是您的测试类中的static
嵌套类,则会自动注册。
答案 1 :(得分:3)
@Import({MyTestConfiguration.class})
在测试中显式导入测试配置。@Bean
和@Configuration
中@TestConfiguration
方法的名称必须不同。至少在Spring Boot v2.2中有所不同。spring.main.allow-bean-definition-overriding=true
否则将无法覆盖该bean。答案 2 :(得分:2)
确保@Bean工厂方法的方法名称与任何现有的Bean名称都不匹配。我在方法名称上遇到问题,例如 config()或(就我而言) prometheusConfig()与现有的Bean名称冲突。 Spring会静静地跳过那些工厂方法,只是不调用它们/不实例化bean。
如果要在测试中覆盖bean定义,请在@Bean(“ beanName”)批注中显式使用bean名称作为字符串参数。
答案 3 :(得分:0)
对我来说是这样的代码:
@TestConfiguration // 1. necessary
public class TestMessagesConfig {
@Bean
@Primary // 2. necessary
public MessageSource testMessageSource() { // 3. different method name than in production code e.g. add test prefix
}
}