Spring Bootでmockitoを使ってテストする

求人
Spring Bootでmockitoを使ってテストする

Spring Bootのgradle.buildで以下があればJUnit,mockito,assertJが使えます。

Spring BootのRESTControllerをJUnit4でテストする」にも書きましたが、今回はサービスクラスで使用しているリポジトリクラスをモックする一般的なテスト方法を書いてみます。

サービスクラスのメソッド内でリポジトリクラス経由でDBにアクセスしています。

DemoServiceTest.java

サービスクラスがテスト対象なので@IngectMocksをつけます。

サービスクラスのメソッドで使用するリポジトリに対して@Mockをつけます。@Mockをつけるのはサービスクラスでモックしたいクラスのみです。

@BeforeでMockitoAnnotations.initMocks(this);をしておかないと正常にモックが動作しません。

テストメソッドで、whenの引数にメソッドを指定します。thenThrow(new RuntimeException());でランタイムエクセプションをスローさせます。これでcatch句に遷移させることができます。スローさせずに値を返したい場合はthenReturnメソッドを使用します。

以下はサービスクラスです。

when().thenThrow()で注意

findAll()のような引数のないメソッドはthenThrow()されますが、自作のメソッドで引数が存在する場合はany()などを使用する必要があります。

例えば

というようにすると正常に動作しません。この場合、String型の引数なので以下のように記述します。

というようにanyString()を使用します。引数がオブジェクトの場合はany()を使用します。

上記をstaticインポートすればOKです。

@RunWith(MockitoJUnitRunner.class)アノテーションでモックする

@RunWith(MockitoJUnitRunner.class)をクラスにつけることによってモックすることも可能です。

@Beforeの部分は不要になります。

when~thenThrowが使えない場合がある

when~thenThrowでスローさせようとしていたのですが、どうも戻り値がvoidのメソッドに対してはwhen~thenThrowが使えないようです。「型 Mockito のメソッド when(T) は引数 (void) に適用できません」とエラーになると思います。個人的にこちらはお勧めしません。

代わりにdoThrow~when、doReturn~when、doAnswer~whenを使います。使用方法は以下のような感じです。

whenの引数はインスタンスでそのメソッドをwhenの中ではなく、外でチェーンします。

これで戻り値がvoid型のメソッドもスローが出来るようになります。when~thenThrowより全てのテストケースでdoThrow~whenを使った方が良い気がします。

assertはassertThatExceptionOfTypeを使用します。

これでuploadメソッドが実行したときにXXExceptionが発生すればテストOKとなります。

mockitoではプライベートメソッドをモックすることができない

JMockitoならプライベートメソッドをモックすることができるのですが、mockitoではプライベートメソッドをモックすることができませんので注意です。

mockitoでプライベートメソッドをリフレクションでテストする

mockitoではプライベートメソッドをモックすることができませんが、プライベートメソッドのテストをすることは可能です。

以下のようにgetDeclaredMethodを使用します。

setAccessible(true)にしておきます。これでプライベートメソッド(上記ではcalcメソッド)のテストができます。

mockitoでコーディングする際、以下はstatic importしておきたいです。

メソッドが呼ばれた回数を確認する

verifyでモックしたメソッドが呼ばれた回数を確認するテストをすることができます。

以下のように書きます。

上記は、findByPk()メソッドが2回呼ばれていることを確認します。

サンプルテストコードです。

Please remove unnecessary stubbings or use ‘lenient’ strictness. More info: javadoc for UnnecessaryStubbingException class.

このエラーが出たら、使ってもいないインスタンスをモックしているというエラーです。

簡単に解決するには、@RunWith(Mockito.JUnitRunner.classを以下のように変更します。

これでエラーがでなくなります。

スポンサーリンク
  • このエントリーをはてなブックマークに追加
スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA