web-dev-qa-db-ja.com

Spring Boot:統合テスト中に@TestConfigurationがBeanをオーバーライドしない

@Configurationで装飾されたクラスでBeanが定義されています:

@Configuration
public class MyBeanConfig {

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

このBeanをオーバーライドする@TestConfigurationで装飾されたクラスがあります。

@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()メソッドがヒットし、String@AutowiredMyParsingComponentは、予想される../production/environment/pathではなく常に/test/environment/pathになります。

なぜこれが起こっているのか分かりません。どんな考えでも大歓迎です。

19
The Head Rush

Spring Bootリファレンスマニュアルの Detecting Test Configuration セクションに記載されているように、@TestConfigurationアノテーションが付けられた最上位クラスで設定されたBeanはnotコンポーネントスキャンを介して取得されます。したがって、@TestConfigurationクラスを明示的に登録する必要があります。

テストクラスで@Import(MyTestConfiguration.class)または@ContextConfiguration(classes = MyTestConfiguration.class)のいずれかを使用して実行できます。

一方、@TestConfigurationアノテーションが付けられたクラスがstaticネストされたクラスwithinテストクラスである場合、それは自動的に登録されます。

37
Sam Brannen

@Beanファクトリメソッドのメソッド名が既存のBean名と一致しないことを確認してください。 config()または(私の場合)prometheusConfig()既存のBean名と衝突しました。 Springはこれらのファクトリメソッドをスキップしますサイレント単にそれらを呼び出したり、Beanをインスタンス化しません。

テストでBean定義をオーバーライドする場合は、@ Bean( "beanName")アノテーションの文字列パラメーターとしてBean名を明示的に使用します。

4
Marcel Thimm