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

时间:2018-05-30 14:29:56

标签: java spring-boot spring-test

我在用@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 }。

不确定为什么会这样。任何想法都将不胜感激。

4 个答案:

答案 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

    }
  }