1. HOME
  2. ブログ
  3. IT技術
  4. Junitでモックを使ってみよう!
Junitでモックを使ってみよう!

Junitでモックを使ってみよう!

はじめに

現在、所属しているプロジェクトではSpring Bootを使用したAPI開発と、Junitを利用したユニットテストを実施しています。

ユニットテストをしていると、依存しているオブジェクトがまだ未完成でテストができないよー、という状況に一度は遭遇されたことがあるのではないでしょうか。

そういった時にモックを使ってテストを実施する方法を簡単に紹介したいと思います。

Junitとは

JUnitとは、Java言語で開発されたプログラムの単体テスト(ユニットテスト)を行なうためのソフトウェア。また、そこで用いられるテストコードの記述体系を含むテストフレームワーク。

出典:https://e-words.jp/w/JUnit.html

Junitバージョン

Junit5.7

モックやスタブとは?

モックに似ている言葉としてスタブがあります。モックもスタブも意味が似ていて混乱したのでまずはモック、スタブの各用語の意味についてネットで調べて整理してみました。

スタブ

依存するオブジェクトの代用となるオブジェクトのことです。テストではスタブに任意の戻り値を設定して、予測可能な動作をするようにして使います。

モック

モックは依存しているオブジェクトのメソッドの呼び出し回数の検証など、依存オブジェクトが正しく利用されているかの検証をするのが主な目的のようです。一方でスタブの機能を併せ持っていることがあるらしく、依存するオブジェクトの代用としての意味も持っているようでした。

Junitにおけるモック、スタブ

Junit単体ではモック、スタブ機能は提供されていないので、外部のライブラリを利用します。ライブラリは色々あるみたいですが、Mockitoライブラリを利用する方法が一般的のようです。

Mockitoではモック機能はスタブ機能の上位互換として提供されています。そのため、まずはどちらを利用するにしても後述するMockitoクラスのmockメソッドを使いモックオブジェクトを作成して、モックオブジェクトをモック、スタブとして利用することになります。

モック、スタブのどちらの場合も後述するmockメソッドで作成しますが、メソッド呼び出しの回数検証などを実施するならばモックとして機能して、メソッドの戻り値などを設定して代用として利用するならば、スタブとして機能するイメージです。

私の感覚だとJunitに限らずスタブよりモックという言葉がより使われていて、また、モックをスタブ的な意味で使われていることが多いかなと感じています。本稿ではモック、モックオブジェクトを「まだ完成していない機能の代用」というスタブ的な意味としても使おうと思います。

Mockitoを使用してモックを使ってみる

モックに予測可能な値を戻すメソッドを定義し、未完成のオブジェクトの代用として使用することでテストができるようになります。

Junitでモックオブジェクトの作成、メソッドの定義、モックの設定、モックしたメソッドの検証方法について説明します。

モックオブジェクトの作成

org.mockito.Mockitoクラスのmockメソッドを用いてモックオブジェクトを作成して、引数にはモックしたいクラスを指定します。mockメソッドを用いて作成されたモックオブジェクトは全てのメソッドがnullを返すメソッドとして設定されます。テストでは適切にモックしたい各メソッドの戻り値を設定しておく必要があります。

以下はListをモック化した例です。

※ 一部のメソッドのみ定義を変えたい場合はspyを利用する必要があります

モックオブジェクトのメソッドの定義

モックに予測可能な値を戻す(戻り値、例外)メソッドを定義する方法を説明します。

2通りの記法

メソッドをモック化する記法は前置記法と後置記法の2通りがあります。どちらを利用するかですが、後置記法では利用できないパターンがあるので、前置記法を利用したほうがよさそうです。
私が所属しているプロジェクトでも前置記法で統一していました。

以下、後置記法では利用できないこと

  • 戻り値Voidのメソッドを定義できない
  • スパイオブジェクトでは利用できない

戻り値の設定

モックオブジェクトを作成したらモックしたいメソッドの戻り値を設定します。メソッドの指定した引数で呼び出された時の戻り値を設定します。anyInt()やanyString()はメソッドの引数の型定義に従って設定する必要があります。

例外の設定

実際に例外を発生させる条件が複雑な場合でも例外を発生させるようにモックを設定することで、簡単に例外のテストを試すことができます。

一部のメソッドをモックしたい場合

mockメソッドを使用した場合、全てのメソッドの戻り値がnullに設定されています。そこで、一部のメソッドのみをモックしたい時はspyメソッドを利用して一部だけのメソッドの戻り値を定義することが可能です。

テスト対象クラスへのモックオブジェクトの設定

あとはテスト対象クラスのフィールドに依存しているオブジェクトに変わってモックオブジェクトを設定します。テストを実行すると定義したモックオブジェクトの予測可能なメソッドが実行されるようになります。

verifyメソッドによる検証

テスト対象クラスにモック化したオブジェクトを設定して、テストを実施します。テストではクラスの仕様が満たされていることを確認しつつ、モック化したオブジェクトがちゃんと動作しているかの検証をします。

以下ではメソッド呼び出し回数を検証しています。

アノテーションを利用したモックオブジェクト

Spring Bootを使用したアプリケーションのテストでよく使用するモック関連のアノテーションについて簡単に紹介します。

@Mockと@Spy

Mockitoから提供されるアノテーションで、mockメソッド、spyメソッドの省略形です。フィールドのモック化するオブジェクトに@Mockや@Spyを指定します。@InjectMocksアノテーションでテスト対象のクラスに対してモック化したオブジェクトをインジェクションします。

@MockBeanと@SpyBean

Spring Bootが提供しているモック。

上述の@Mock、@Spyと同じような使い方をしますが、大きな違いはアプリケーションコンテキスト(DIコンテナ)にオブジェクトが登録されることです。

さいごに

以上、Junitを使用したモックの利用方法について簡単ではありますが紹介させて頂きました。

テストするクラスが他のオブジェクトに依存していて、依存先のオブジェクトがまだ未完成だという状況は往々にしてあると思いますが、モックを利用すると依存しているオブジェクトの有無にかかわらずユニットテストを実施することができるようになります。

この記事がこれからJunitを利用してテストする方のお役に立てれば幸いです。

最後までご覧頂きまして、ありがとうございました。

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア