Java Spring Boot:@TestConfiguration 在集成测试期间不覆盖 Bean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50607285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:42:28  来源:igfitidea点击:

Spring Boot: @TestConfiguration Not Overriding Bean During Integration Test

javaspring-bootspring-test

提问by The Head Rush

I have a Beandefined in a class decorated with @Configuration:

Bean在用@Configuration 装饰的类中定义了一个:

@Configuration
public class MyBeanConfig {

    @Bean
    public String configPath() {
        return "../production/environment/path";
    }
}

I have a class decorated with @TestConfiguration that should override this Bean:

我有一个用@TestConfiguration 装饰的类,它应该覆盖这个Bean

@TestConfiguration
public class MyTestConfiguration {

    @Bean
    @Primary
    public String configPath() {
        return "/test/environment/path";
    }
}

The configPathbean is used to set the path to an external file containing a registration code that must be read during startup. It is used in an @Component class:

所述configPath豆用于将路径设置为包含必须在启动期间读取的注册代码的外部文件。它用于@Component 类:

@Component
public class MyParsingComponent {

    private String CONFIG_PATH;

    @Autowired
    public void setCONFIG_PATH(String configPath) {
        this.CONFIG_PATH = configPath;
    }
}

While trying to debug this, i set a breakpoint inside each method as well as the constructor of the test config class. The @TestConfiguration's constructor breakpoint is hit, so i know that my test configuration class instantiates, however the configPath()method of that class is never hit. Instead, the configPath()method of the normal @Configuration class is hit and the @AutowiredStringin MyParsingComponentis always ../production/environment/pathrather than the expected /test/environment/path.

在尝试调试时,我在每个方法以及测试配置类的构造函数中设置了一个断点。在@TestConfiguration类的构造函数断点命中,所以我知道我的测试配置类实例化,但是configPath()该类的方法不会被击中。相反,configPath()普通 @Configuration 类的方法被命中并且@AutowiredStringinMyParsingComponent总是../production/environment/path而不是预期的/test/environment/path

Not sure why this is happening. Any thoughts would be greatly appreciated.

不知道为什么会这样。任何想法将不胜感激。

采纳答案by Sam Brannen

As documented in the Detecting Test Configurationsection of the Spring Boot reference manual, any beans configured in a top-level class annotated with @TestConfigurationwill notbe picked up via component scanning. So you have to explicitly register your @TestConfigurationclass.

正如Spring Boot 参考手册的Detecting Test Configuration部分所记录的那样,在顶级类中配置的任何 bean@TestConfiguration不会通过组件扫描来获取。所以你必须明确注册你的@TestConfiguration课程。

You can do that either via @Import(MyTestConfiguration.class)or @ContextConfiguration(classes = MyTestConfiguration.class)on your test class.

你可以通过@Import(MyTestConfiguration.class)@ContextConfiguration(classes = MyTestConfiguration.class)在你的测试类上做到这一点。

On the other hand, if your class annotated with @TestConfigurationwere a staticnested class withinyour test class, it would be registered automatically.

在另一方面,如果你有注解的类@TestConfiguration是一个static嵌套类的测试类,它会自动注册。

回答by Marcel Thimm

Make sure that the method name of your @Bean factory method does not match any existing bean name. I had issues with method names like config()or (in my case) prometheusConfig()which collided with existing bean names. Spring skips those factory methods silentlyand simply does not call them / does not instantiate the beans.

确保您的 @Bean 工厂方法的方法名称与任何现有的 bean 名称都不匹配。我遇到了config()或(在我的情况下) prometheusConfig()等方法名称与现有 bean 名称冲突的问题。Spring 会默默地跳过这些工厂方法,只是不调用它们/不实例化 bean。

If you want to override a bean definition in your test, use the bean name explicitly as string parameter in your @Bean("beanName") annotation.

如果要覆盖测试中的 bean 定义,请在 @Bean("beanName") 注释中显式使用 bean 名称作为字符串参数。

回答by Maksim Sorokin

  • Test configuration has to be explicitly imported in the test via @Import({MyTestConfiguration.class}).
  • The name of the @Beanmethods in @Configurationand @TestConfigurationhave to be different. At least it makes difference in Spring Boot v2.2.
  • Also make sure spring.main.allow-bean-definition-overriding=trueotherwise the bean could not be overriden.
  • 测试配置必须通过@Import({MyTestConfiguration.class}).
  • 的名称@Bean的方法@Configuration,并@TestConfiguration有不同。至少它在 Spring Boot v2.2 中有所不同。
  • 还要确保spring.main.allow-bean-definition-overriding=true否则无法覆盖 bean。