@MockitoBean および @MockitoSpyBean

@MockitoBean (Javadoc) @MockitoSpyBean (Javadoc) は、テストクラスで使用して、テストの ApplicationContext の Bean をそれぞれ Mockito mock または spy でオーバーライドできます。後者の場合、元の Bean の初期インスタンスがスパイによってキャプチャーされ、ラップされます。

アノテーションは次の方法で適用できます。

  • テストクラスまたはそのスーパークラスの非静的フィールド。

  • @Nested テストクラスの包含クラス内の非静的フィールド、または @Nested テストクラスの上位の型階層または包含クラス階層内の任意のクラス。

  • テストクラスの型レベル、またはテストクラスの上位の型階層内の任意のスーパークラスまたは実装されたインターフェース。

  • @Nested テストクラスの包含クラスの型レベル、または @Nested テストクラスの上位の型階層または包含クラス階層内の任意のクラスまたはインターフェース。

フィールドで @MockitoBean または @MockitoSpyBean が宣言されている場合、モックまたはスパイする Bean は、アノテーションが付けられたフィールドの型から推論されます。ApplicationContext に複数の候補が存在する場合は、曖昧さを解消するために、フィールドに @Qualifier アノテーションを宣言できます。@Qualifier アノテーションがない場合、アノテーションが付けられたフィールドの名前がフォールバック修飾子として使用されます。または、アノテーションで value または name 属性を設定することで、モックまたはスパイする Bean 名を明示的に指定することもできます。

@MockitoBean または @MockitoSpyBean が型レベルで宣言されている場合、モックまたはスパイする Bean (または Bean) の型は、アノテーションの types 属性を介して指定する必要があります (例: @MockitoBean(types = {OrderService.class, UserService.class}))。ApplicationContext に複数の候補が存在する場合は、name 属性を設定することで、モックまたはスパイする Bean 名を明示的に指定できます。ただし、明示的な Bean name が構成されている場合 (例: @MockitoBean(name = "ps1", types = PrintingService.class))、types 属性には単一の型が含まれている必要があることに注意してください。

モック構成の再利用をサポートするために、@MockitoBean と @MockitoSpyBean をメタアノテーションとして使用して、カスタム合成アノテーションを作成できます。たとえば、テストスイート全体で再利用できる単一のアノテーションで共通のモック構成またはスパイ構成を定義できます。@MockitoBean と @MockitoSpyBean は、型レベルで繰り返し可能なアノテーションとして使用することもできます。たとえば、名前で複数の Bean をモックまたはスパイできます。

フィールド名などの修飾子は、別の ApplicationContext を作成する必要があるかどうかを判断するために使用されます。この機能を使用して、複数のテストクラスで同じ Bean をモックまたはスパイする場合は、不要なコンテキストを作成しないように、フィールドに一貫した名前を付けるようにしてください。

各アノテーションは、モック動作を微調整するための Mockito 固有の属性も定義します。

@MockitoBean アノテーションは、Bean オーバーライドに REPLACE_OR_CREATE 戦略を使用します。対応する Bean が存在しない場合は、新しい Bean が作成されます。ただし、enforceOverride 属性を true (例: @MockitoBean(enforceOverride = true)) に設定することで、REPLACE 戦略に切り替えることができます。

@MockitoSpyBean アノテーションは WRAP  戦略を使用し、元のインスタンスは Mockito スパイにラップされます。この戦略では、候補となる Bean が 1 つだけ存在する必要があります。

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

@MockitoBean を使用して FactoryBean によって作成された Bean をモックする場合、FactoryBean は FactoryBean によって作成されたオブジェクトの型のシングルトンモックに置き換えられます。

@MockitoSpyBean を使用して FactoryBean のスパイを作成すると、FactoryBean 自体ではなく、FactoryBean によって作成されたオブジェクトに対してスパイが作成されます。

@MockitoBean フィールドと @MockitoSpyBean フィールドの可視性には制限はありません。

このようなフィールドは、プロジェクトのニーズやコーディング方法に応じて、publicprotected、パッケージプライベート (デフォルトの可視性)、または private になります。

@MockitoBean の例

次の例は、@MockitoBean アノテーションのデフォルトの動作を使用する方法を示しています。

  • Java

@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {

	@MockitoBean (1)
	CustomService customService;

	// tests...
}
1Mockito モックを使用して、Bean を型 CustomService に置き換えます。

上記の例では、CustomService のモックを作成しています。その型の Bean が複数存在する場合は、customService という名前の Bean が考慮されます。そうでない場合、テストは失敗し、オーバーライドする CustomService Bean を識別するために何らかの修飾子を指定する必要があります。そのような Bean が存在しない場合は、自動生成された Bean 名で Bean が作成されます。

次の例では、型による検索ではなく、名前による検索を使用します。service という名前の Bean が存在しない場合は、作成されます。

  • Java

@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {

	@MockitoBean("service") (1)
	CustomService customService;

	// tests...

}
1service という名前の Bean を Mockito モックに置き換えます。

次の @SharedMocks アノテーションは、型によるモック 2 つと名前によるモック 1 つを登録します。

  • Java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoBean(types = {OrderService.class, UserService.class}) (1)
@MockitoBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedMocks {
}
1OrderService および UserService モックを型別に登録します。
2PrintingService のモック名を登録します。

以下は、@SharedMocks をテストクラスで使用する方法を示しています。

  • Java

@SpringJUnitConfig(TestConfig.class)
@SharedMocks (1)
class BeanOverrideTests {

	@Autowired OrderService orderService; (2)

	@Autowired UserService userService; (2)

	@Autowired PrintingService ps1; (2)

	// Inject other components that rely on the mocks.

	@Test
	void testThatDependsOnMocks() {
		// ...
	}
}
1 カスタム @SharedMocks アノテーションを介して共通モックを登録します。
2 必要に応じて、モックを挿入してスタブ化または検証します
モックは、@Configuration クラスまたは ApplicationContext 内のその他のテスト関連コンポーネントに挿入して、Mockito のスタブ API を使用して構成することもできます。

@MockitoSpyBean の例

次の例は、@MockitoSpyBean アノテーションのデフォルトの動作を使用する方法を示しています。

  • Java

@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {

	@MockitoSpyBean (1)
	CustomService customService;

	// tests...
}
1Bean を型 CustomService で Mockito スパイでラップします。

上記の例では、Bean を型 CustomService でラップしています。その型の Bean が複数存在する場合は、customService という名前の Bean が考慮されます。そうでない場合、テストは失敗し、スパイする CustomService Bean を識別するために何らかの修飾子を提供する必要があります。

次の例では、型による検索ではなく、名前による検索を使用します。

  • Java

@SpringJUnitConfig(TestConfig.class)
class BeanOverrideTests {

	@MockitoSpyBean("service") (1)
	CustomService customService;

	// tests...
}
1service という名前の Bean を Mockito スパイでラップします。

次の @SharedSpies アノテーションは、型別に 2 つのスパイと名前別に 1 つのスパイを登録します。

  • Java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MockitoSpyBean(types = {OrderService.class, UserService.class}) (1)
@MockitoSpyBean(name = "ps1", types = PrintingService.class) (2)
public @interface SharedSpies {
}
1OrderService および UserService スパイを型別に登録します。
2PrintingService スパイの名前を登録します。

以下は、@SharedSpies をテストクラスで使用する方法を示しています。

  • Java

@SpringJUnitConfig(TestConfig.class)
@SharedSpies (1)
class BeanOverrideTests {

	@Autowired OrderService orderService; (2)

	@Autowired UserService userService; (2)

	@Autowired PrintingService ps1; (2)

	// Inject other components that rely on the spies.

	@Test
	void testThatDependsOnMocks() {
		// ...
	}
}
1 カスタム @SharedSpies アノテーションを介して共通スパイを登録します。
2 オプションでスパイを挿入してスタブ化または検証します
スパイは、@Configuration クラスまたは ApplicationContext 内のその他のテスト関連コンポーネントに挿入して、Mockito のスタブ API を使用して構成することもできます。