Javaによるテスト入門
Maria Milusheva
Senior Software Engineer
前のレッスンと演習では、戻り値に対してアサートしました。
しかし、戻り値がない場合は?
戻り値が重要でない/情報が少ない場合は?
例: データベースへの保存。

データベース: データを整理して保存・管理・保護するデジタルな保管庫。多くのプロバイダーがあります。

データベースサーバーは耐久・安全・信頼性が高く、容量は実質無制限
本物のデータベースは単体テストには大きく複雑(結合テストでは使用可)
ログを処理するとします。
public class MessageProcessor {
private InfoStore infoStore; // 情報ログを保存
private ErrorStore errorStore; // エラーログを保存
public void saveMessage(String message) {
if (message.startsWith("[INFO]")) {
infoStore.save(message);
}
if (message.startsWith("[ERROR]")) {
errorStore.save(message);
}
}
}
テストに必要なのは基本的なインターフェースだけです。
// InfoStore と ErrorStore の設計図
// モックは実装がなくても動作します
interface InfoStore {
void save(String message);
}
interface ErrorStore {
void save(String message);
}
データベースを作らずに、保存されたことをどうテストしますか?
モックが使われたことを検証:
import static org.mockito.Mockito.verify;
モックが使われなかったことを検証:
import static org.mockito.Mockito.verifyNoInteractions;
@Test void process_savesToInfoStore_whenInfoMessage() { InfoStore infoStore = mock(InfoStore.class); ErrorStore errorStore = mock(ErrorStore.class); MessageProcessor messageProcessor = new MessageProcessor(infoStore, errorStore);String message = "[INFO] Process started."; messageProcessor.saveMessage(message); // Will use either InfoStore or ErrorStore// どちらのデータベースが使われたかを検証 verify(infoStore).save(message); verifyNoInteractions(errorStore); }
作成するメッセージが次のような場合はどうでしょう。
String message = "[ERROR] Process failed!"
次のようなテスト失敗が発生します:
Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
呼び出し回数も正確に検証できます。
import static org.mockito.Mockito.times;
List<String> messages = new ArrayList<>(); // リストを作成して要素を追加 messages.add("[INFO] Processing data..."); messages.add("[INFO] Processing data..."); messages.add("[INFO] Processing data..."); messageProcessor.saveMessageList(messages); // 3件を保存verify(infoStore, times(3)).save("[INFO] Processing data...");
Javaによるテスト入門