@ComponentScan
のテストでは、@ComponentScan
の問題が発生しました。つまり、@ComponentScan
が統合テスト中に意図せずに引き込まれています。例えば@ComponentScanのテストクラスの設定を除外
、com.example.config.GlobalConfiguration
、あなたがcom.example.service
内のコンポーネントに引っ張るsrc/main/java
でいくつかのグローバル設定を持っていると言う:
package com.example.config;
...
@Configuration
@ComponentScan(basePackageClasses = ServiceA.class)
public class GlobalConfiguration {
...
}
2つのサービス、com.example.services.ServiceA
とcom.example.services.ServiceB
に引っ張るためのものだ、@Component
と@Profile("!test")
で注釈を付け(簡略化のため省略されている)。 SRC /テスト/ javaの、com.example.services.ServiceATest
で次に
:
package com.example.services;
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ServiceATest.ServiceATestConfiguration.class)
public class ServiceATest {
...
@Configuration
public static class ServiceATestConfiguration {
@Bean
public ServiceA serviceA() {
return ServiceA(somemocking...);
}
}
}
もcom.example.ServiceBIntegrationTest
、統合テストであるためにGlobalConfiguration.class
にプルする必要がありますが、それでも@ActiveProfiles("test")
と危険な実装で引っ張って回避:
package com.example.services;
...
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {GlobalConfiguration.class, ServiceBIntegrationTest.ServiceBIntegrationTestConfiguration.class})
public class ServiceBIntegrationTest {
...
@Configuration
public static class ServiceBIntegrationTestConfiguration {
@Bean
public ServiceB serviceB() {
return ServiceB(somemocking...);
}
}
}
ServiceBIntegrationTest
の明白な意図は、危険な除外GlobalConfiguration
を経由して、完全なsrc/main/java
アプリケーション構成で引っ張っていますコンポーネントを@ActiveProfiles("test")
経由で削除し、除外されたコンポーネントを独自の実装に置き換えます。しかし、テスト中にsrc/main/java
とsrc/test/java
という名前空間が組み合わされているため、GlobalConfiguration
の@ComponentScan
は、通常よりもクラスパスのほうが多く、つまり、ServiceA.ServiceATestConfiguration
で定義されたServiceA
のBeanを検出します。それは容易に矛盾や意図しない結果につながる可能性があります。
GlobalConfiguration
のようなものを@ComponentScan(..., excludeFilters= @ComponentScan.Filter(type = FilterType.REGEX, pattern = "\\.*(T|t)est\\.*"))
とすることもできますが、それ自体に問題があります。命名規則に頼っているのはかなり脆弱です。たとえあなたが@TestConfiguration
注釈を無効にしてFilterType.ANNOTATION
を使用したとしても、をご存知であれば、あなたのsrc/test/java
を認識させることになります。注:下記のを参照してください。
私の問題は、追加プロファイルを使用して解決しました。 ServiceA
に、固有のプロファイル名を追加します。そのプロファイルの注釈は@ActiveProfiles("test,serviceatest")
のようになります。次に、ServiceATest.ServiceATestConfiguration
に、@Profile("serviceatest")
の注釈を追加します。これは、効果的に比較的少ないオーバーヘッドでServiceATestConfiguration
の範囲を制限しますが、それは次のようにどちらかのようだ:私は間違って@ComponentScan
を使用していますa)の
、または
b)は、この問題
を処理するための非常にクリーンパターンがあるはずですどちらですか?
ノート:はい、それは@Profile("!test")
を使用していますので、アプリがテスト認識しているが、私は不適切なリソースの使用状況から身を守るために少しテスト対応のアプリケーションを作成して確保することがテストを意識した作りと主張したいですテストの正確さは非常に異なるものです。
ええ、そのパターンにはいくつかの利点がありますが、それは私の質問についてではありません。私は、コンポーネントスキャンパッケージ内の構成の範囲を最大限に制限する方法を求めています。 – jwilner
パッケージを変更すると、パッケージのローカルスコープと競合する可能性があります。これはテストでは明らかに重要です。これは不満足です。 – jwilner