テストでの Bean のオーバーライド

テストでの Bean オーバーライドとは、テストクラス内の 1 つ以上のフィールドにアノテーションを付けることで、テストクラスの ApplicationContext 内の特定の Bean をオーバーライドする機能を指します。

この機能は、DefaultListableBeanFactorysetAllowBeanDefinitionOverriding フラグを true に設定して @Bean 経由で Bean を登録する方法よりもリスクの少ない代替手段として意図されています。

Spring TestContext フレームワークは、Bean オーバーライド用のアノテーションを 2 セット提供します。

前者は純粋に Spring に依存し、後者のセットは Mockito (英語) サードパーティライブラリに依存します。

カスタム Bean オーバーライドサポート

上記の 3 つのアノテーションは、@BeanOverride メタアノテーションと関連インフラストラクチャに基づいて構築されており、カスタム Bean オーバーライドバリアントを定義できます。

カスタム Bean オーバーライドサポートを実装するには、次のものが必要です。

  • 使用する BeanOverrideProcessor を定義する @BeanOverride でアノテーションされたアノテーションメタ

  • カスタム BeanOverrideProcessor 実装

  • プロセッサーによって作成された 1 つ以上の具体的な BeanOverrideHandler 実装

Spring TestContext フレームワークには、Bean オーバーライドをサポートし、インフラストラクチャの残りの部分を設定する次の API の実装が含まれています。

  • BeanFactoryPostProcessor

  • ContextCustomizerFactory

  • TestExecutionListener

spring-test モジュールは、後者の 2 つ (BeanOverrideContextCustomizerFactory と BeanOverrideTestExecutionListener) の実装を META-INF/spring.factories プロパティファイル [GitHub] (英語) に登録します。

Bean オーバーライドインフラストラクチャは、テストクラス内で @BeanOverride でアノテーションが付けられたフィールドメタを検索し、適切な BeanOverrideHandler を作成するロールを持つ対応する BeanOverrideProcessor をインスタンス化します。

次に、内部の BeanOverrideBeanFactoryPostProcessor は Bean オーバーライドハンドラーを使用して、対応する BeanOverrideStrategy で定義されているように Bean を作成、置換、ラップすることにより、テストの ApplicationContext を変更します。

REPLACE

Bean を置き換えます。対応する Bean が存在しない場合は例外をスローします。

REPLACE_OR_CREATE

Bean が存在する場合は置き換えます。対応する Bean が存在しない場合は、新しい Bean を作成します。

WRAP

オリジナルの Bean を取り出し、折り返しします。

オーバーライドできるのはシングルトン Bean のみです。非シングルトン Bean をオーバーライドしようとすると、例外が発生します。

FactoryBean によって作成された Bean を置き換える場合、FactoryBean 自体は、該当する BeanOverrideHandler によって作成された Bean オーバーライドインスタンスに対応するシングルトン Bean に置き換えられます。

FactoryBean によって作成された Bean をラップする場合、FactoryBean 自体ではなく、FactoryBean によって作成されたオブジェクトがラップされます。

Spring のオートワイヤーメカニズム (たとえば、@Autowired フィールドの解決) とは対照的に、TestContext フレームワークの Bean オーバーライドインフラストラクチャでは、Bean を見つけるために実行できるヒューリスティックが限られています。BeanOverrideProcessor はオーバーライドする Bean の名前を計算するか、アノテーション付きフィールドの型とその修飾アノテーションに基づいて明確に選択することができます。

通常、Bean は BeanOverrideFactoryPostProcessor によって「型別」に選択されます。あるいは、ユーザーはカスタムアノテーションで Bean 名を直接指定することもできます。

BeanOverrideProcessor 実装では、規則またはその他の方法に基づいて Bean 名を内部的に計算する場合もあります。