BDDMockitoのクイックガイド
1概要
-
BDD用語は最初にhttps://dannorth.net/introducing-bdd/[Dan North – 2006年に戻って]によって造られました。**
BDDは、アプリケーションの動作に焦点を当てた、人間が読める自然な言語でテストを書くことを推奨します。
それは3つのセクション(アレンジ、アクト、アサート)に続くテストを書くことの明確に構造化された方法を定義します:
-
__前提条件(手配)
-
アクションが発生したとき(Act)
-
出力を確認します(アサート)
-
Mockitoライブラリには、BDDフレンドリなAPIを導入する
BDDMockito
クラスが付属しています** このAPIを使用すると、
given()
を使用してテストを調整し、
then()
を使用してアサーションを作成できます。
この記事では、BDDベースのMockitoテストを設定する方法について説明します。また、最終的には
BDDMockito
APIに焦点を合わせるために、
Mockito
と
BDDMockito
APIの違いについても説明します。
2セットアップ
2.1. Mavenの依存関係
-
MockitoのBDDフレーバーは
mockito-core
ライブラリの一部です** 、始めるにはアーティファクトを含めるだけです。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.21.0</version>
</dependency>
最新バージョンのMockitoについては、https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.mockito%22%2C%20a%3A%22mockito-core%22[Mavenをチェックしてください。中央]。
2.2. 輸入品
次の静的インポートを含めると、テストが読みやすくなります。
import static org.mockito.BDDMockito.** ;
BDDMockito
は
Mockito
を拡張しているので、従来の
Mockito
APIが提供する機能を見逃すことはありません。
3 MockitoとBDDMockito
Mockitoでの伝統的なモッキングは、配置ステップで
when(obj)
.
、次に** ()
を使って実行されます。
後で、Assertステップで
verify()
を使用して、モックとの対話を検証できます。
-
BDDMockito
はさまざまな
Mockito
メソッドのBDDエイリアスを提供するので、(
when
の代わりに)
given
を使用してアレンジステップを記述できます。同様に、(
verify
の代わりに)
then
を使用してアサートステップを記述できます。
伝統的なMockitoを使ったテストボディの例を見てみましょう。
when(phoneBookRepository.contains(momContactName))
.thenReturn(false);
phoneBookService.register(momContactName, momPhoneNumber);
verify(phoneBookRepository)
.insert(momContactName, momPhoneNumber);
それが
BDDMockito
とどのように比較されるかを見てみましょう:
given(phoneBookRepository.contains(momContactName))
.willReturn(false);
phoneBookService.register(momContactName, momPhoneNumber);
then(phoneBookRepository)
.should()
.insert(momContactName, momPhoneNumber);
4
BDDMockito
でモッキングする
PhoneBookRepositoryをモックする必要がある
PhoneBookService
をテストしてみましょう:
public class PhoneBookService {
private PhoneBookRepository phoneBookRepository;
public void register(String name, String phone) {
if(!name.isEmpty() && !phone.isEmpty()
&& !phoneBookRepository.contains(name)) {
phoneBookRepository.insert(name, phone);
}
}
public String search(String name) {
if(!name.isEmpty() && phoneBookRepository.contains(name)) {
return phoneBookRepository.getPhoneNumberByContactName(name);
}
return null;
}
}
BDDMockito
as
Mockito
を使用すると、固定または動的な値を返すことができます。例外をスローすることもできます。
4.1. 固定値を返す
__BDDMockitoを使用すると、モックオブジェクトのターゲットメソッドが呼び出されるたびに固定結果を返すようにMockitoを簡単に設定できます。
given(phoneBookRepository.contains(momContactName))
.willReturn(false);
phoneBookService.register(xContactName, "");
then(phoneBookRepository)
.should(never())
.insert(momContactName, momPhoneNumber);
4.2. 動的な値を返す
BDDMockito
を使用すると、値を返すためのより高度な方法を提供できます。入力に基づいて動的な結果を返すことができます。
given(phoneBookRepository.contains(momContactName))
.willReturn(true);
given(phoneBookRepository.getPhoneNumberByContactName(momContactName))
.will((InvocationOnMock invocation) ->
invocation.getArgument(0).equals(momContactName)
? momPhoneNumber
: null);
phoneBookService.search(momContactName);
then(phoneBookRepository)
.should()
.getPhoneNumberByContactName(momContactName);
4.3. 例外を投げる
Mockitoに例外をスローするように指示するのはとても簡単です。
given(phoneBookRepository.contains(xContactName))
.willReturn(false);
willThrow(new RuntimeException())
.given(phoneBookRepository)
.insert(any(String.class), eq(tooLongPhoneNumber));
try {
phoneBookService.register(xContactName, tooLongPhoneNumber);
fail("Should throw exception");
} catch (RuntimeException ex) { }
then(phoneBookRepository)
.should(never())
.insert(momContactName, tooLongPhoneNumber);
given
と
will **
の位置を交換したことに注意してください。戻り値のないメソッドをモックする場合は必須です。
また、(
any
、
eq
)のような引数マッチャーを使用して、固定値ではなく基準に基づいてモックするより一般的な方法を提供しています。
5結論
このクイックチュートリアルでは、BDDMockitoがどのようにしてBDDの類似性をMockitoのテストに反映させようとするのか、および
Mockito
と
BDDMockito
の違いについて説明しました。
いつものように、ソースコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/mockito[over GitHub] – テストパッケージ
com.baeldung.bddmockito
内にあります。