私はシンプルテスト:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SimpleTestConfig.class)
public class SimpleTest {
@Test
public void test() {
assertThat(true);
}
}
そして構成このテストの場合:
@SpringBootApplication
@ComponentScan(basePackageClasses = {
SimpleTestConfig.class,
Application.class
},
excludeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = Starter.class))
public class SimpleTestConfig {
}
私は除外しようとしているスタータークラス
package application.starters;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class Starter {
@PostConstruct
public void init(){
System.out.println("initializing");
}
}
そしてその応用クラスは次のようになります:
package application;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import static org.springframework.boot.SpringApplication.run;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
run(Application.class, args);
}
}
しかし、非常に奇妙な理由でスタータークラスはまだ初期化中です。
なぜComponentScan excludeFilters
私のクラスが除外されないのか誰か説明してくれませんかStarter
?
ベストアンサー1
各コンポーネント スキャンは個別にフィルタリングを行います。Starter.class
を から除外するとSimpleTestConfig
がSimpleTestConfig
初期化されApplication
、 は を@ComponentScan
除外せずに独自Starter
の処理を行います。 ComponentScan を使用するクリーンな方法は、各 ComponentScan が別々のパッケージをスキャンすることです。そうすれば、各フィルターは正常に機能します。2 つの別々の ComponentScan が同じパッケージをスキャンする場合 (テストの場合など)、これは機能しません。
これをトリックする 1 つの方法は、モックStarter
Bean を提供することです。
import org.springframework.boot.test.mock.mockito.MockBean;
public class SimpleTest {
@MockBean
private Starter myTestBean;
...
}
Spring は実際のクラスの代わりにそのモックを使用するため、メソッド@PostConstruct
は呼び出されません。
その他の一般的な解決策:
Application.class
ユニットテストでは直接使用しないでください- クラス
@Profile("!TEST")
にSpringプロファイルとアノテーションを使用するStarter
- クラス
@ConditionalOn...
にSpring Bootアノテーションを使用するStarter