JUnit

JUnitのMockitoで例外処理のテストをしてみた

Mockitoを利用すると、例外を発生させるMockプログラムも作成することができる。
今回は例外処理を含むプログラムをテストするJUnitのプログラムを作成してみたので、共有する。

前提条件

下記記事の「起動ポートの変更」までの手順が完了していること。

IntelliJ IDEA上でGradleを使ってWeb画面のSpring Bootプロジェクトを作成してみたSpring Bootのプロジェクトを新規作成を「IntelliJ IDEA」のメニューから実施しようとしたところ、無料の「Commun...

やってみたこと

  1. テスト対象プログラムの作成
  2. テスト対象プログラムの実行
  3. JUnitのプログラムの作成と実行

 

テスト対象プログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上図の赤枠は、今回記載するサンプルプログラムの内容である。

テスト対象のコントローラクラスの内容は以下の通り。

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.FileNotFoundException;

@Controller
public class DemoController {

    @Autowired
    private DemoComponent demoComponent;

    @RequestMapping("/")
    public String index(Model model){
        String textString;
        try{
            textString = demoComponent.getTextString();
        }catch (Exception e){
            String errMsg;
            if(e instanceof FileNotFoundException){
                errMsg = "ファイルが見つかりませんでした";
            }else{
                errMsg = "入出力例外が発生しました";
            }
            //エラー時はerror.htmlに遷移
            model.addAttribute("errMsg", errMsg);
            return "error";
        }
        //正常時はindex.htmlに遷移
        model.addAttribute("textString", textString);
        return "index";
    }
}



また、上記プログラムから呼び出されるコンポーネントクラスの内容は以下の通り。

package com.example.demo;

import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

@Component
public class DemoComponent {

    public String getTextString() throws IOException{
        StringBuilder sb = new StringBuilder();
        try(BufferedReader br = new BufferedReader(
                new FileReader("C:\\tmp\\test.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        }catch (FileNotFoundException ex1){
            throw ex1;
        }catch (IOException ex2){
            throw ex2;
        }
        return sb.toString();
    }

}
サラリーマン型フリーランスSEという働き方でお金の不安を解消しよう先日、「サラリーマン型フリーランスSE」という働き方を紹介するYouTube動画を視聴しましたので、その内容をご紹介します。 「サ...

さらに、例外が発生しなかった場合に表示される画面のHTMLファイルの内容は以下の通り。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index page</title>
</head>
<body>
    <p th:text="${textString}">
        ここにtextStringの値が設定されます
    </p>
</body>
</html>

また、エラーを表示させる画面のHTMLファイルの内容は以下の通り。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>error page</title>
</head>
<body>
    <p th:text="${errMsg}">
        ここに発生したエラーメッセージが設定されます
    </p>
</body>
</html>



【PR】「Filmora」は初心者でも本格的な動画編集ができる大変便利なツールだった「Filmora」は初心者でも使いやすい動画編集ツールで、テンプレートとして利用できるテキスト・動画・音楽などが充実していると共に、複数...

テスト対象プログラムの実行

テスト対象プログラムを実行する前に、まずは以下のファイル「test.txt」をC:\tmp下に配置する。
プログラム実行前のファイル配置1
プログラム実行前のファイル配置2

上記状態で、Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下の画面(index.html)が表示される。
実行結果(正常時)

C:\tmp 下に「test.txt」が無い状態で、Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下のエラー画面(error.html)が表示される。
実行結果(エラー時)



「CODE×CODE」は、需要の高い技術(AWS, Python等)を習得できるプログラミングスクールスクールだった近年、さまざまな会社でクラウド(特にIaaSやPaaSのパブリッククラウド)の需要が非常に高まっていて、クラウドサービスによるシステム開...

JUnitのプログラムの作成と実行

テスト対象のコントローラクラス「DemoController.java」から呼ばれるコンポーネントクラス「DemoComponent.java」で例外を発生させた場合の、JUnitのサンプルプログラムの内容は以下の通り。

下記の「testDemoControllerNotFoundException」「testDemoControllerIOException」メソッドのように、doThrow句を利用することで、指定したメソッドで指定した例外がスローされるようにMock設定できる。

package com.example.demo;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.*;

import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.ui.Model;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

public class DemoControllerTest {

    /**
     * テスト対象クラス
     */
    @InjectMocks
    private DemoController demoController;

    /**
     * テスト対象のクラス内で呼ばれるクラスのMockオブジェクト
     */
    @Mock
    private DemoComponent demoComponent;

    /**
     * 前処理(各テストケースを実行する前に行われる処理)
     */
    @Before
    public void init() {
        //@Mockアノテーションのモックオブジェクトを初期化
        //これを実行しないと@Mockアノテーション、@InjectMocksを付与した
        //Mockオブジェクトが利用できない
        MockitoAnnotations.initMocks(this);
    }

    /**
     * DemoControllerクラスのindexメソッドの確認
     */
    @Test
    public void testDemoControllerNormal() throws IOException {
        //demoComponent.getTextStringメソッドでIOExceptionが発生し得るので
        //メソッドにthrows句を付与している

        //Mockオブジェクト呼出時の値を設定
        doReturn("abcdeテスト").when(demoComponent).getTextString();

        //modelオブジェクトを取得し、テスト対象クラスのメソッドを実行
        Model model = DemoControllerTestUtil.getModel();
        String returnVal = demoController.index(model);

        //戻り値が"index"であることを確認
        assertEquals("index", returnVal);

        //modelオブジェクトの設定値を確認
        //demoComponent.getTextStringが呼ばれた場合は設定したMockの戻り値が設定され、
        //エラーメッセージが設定されないことを確認
        Map<String, Object> modelValue = model.asMap();
        assertEquals("abcdeテスト", modelValue.get("textString"));
        assertNull(modelValue.get("errMsg"));
    }

    @Test
    public void testDemoControllerNotFoundException() throws IOException {
        //Mockオブジェクト呼出時の例外を設定
        //doThrow句内に例外を設定するが、発生し得ない例外(例:Exception)は設定できない
        doThrow(new FileNotFoundException()).when(demoComponent).getTextString();

        //modelオブジェクトを取得し、テスト対象クラスのメソッドを実行
        Model model = DemoControllerTestUtil.getModel();
        String returnVal = demoController.index(model);

        //戻り値が"error"であることを確認
        assertEquals("error", returnVal);

        //modelオブジェクトの設定値を確認
        //FileNotFoundExceptionが発生した場合のエラーメッセージ「ファイルが
        //見つかりませんでした」が設定され、textStringが設定されないことを確認
        Map<String, Object> modelValue = model.asMap();
        assertEquals("ファイルが見つかりませんでした", modelValue.get("errMsg"));
        assertNull(modelValue.get("textString"));
    }

    @Test
    public void testDemoControllerIOException() throws IOException {
        //Mockオブジェクト呼出時の値を設定
        //doThrow句内に例外を設定するが、発生し得ない例外(例:Exception)は設定できない
        doThrow(new IOException()).when(demoComponent).getTextString();

        //modelオブジェクトを取得し、テスト対象クラスのメソッドを実行
        Model model = DemoControllerTestUtil.getModel();
        String returnVal = demoController.index(model);

        //戻り値が"error"であることを確認
        assertEquals("error", returnVal);

        //modelオブジェクトの設定値を確認
        //IOExceptionが発生した場合のエラーメッセージ「入出力例外が発生しました」が
        //設定され、textStringが設定されないことを確認
        Map<String, Object> modelValue = model.asMap();
        assertEquals("入出力例外が発生しました", modelValue.get("errMsg"));
        assertNull(modelValue.get("textString"));
    }
}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/junit-mockito-exception/demo

「EaseUS Todo Backup」は様々な形でバックアップ取得が行える便利ツールだったパソコン内のデータを、ファイル/パーティション/ディスク等の様々な単位でバックアップしたり、バックアップのスケジュール設定や暗号化設定も...

さらに、上記プログラムを実行した結果は以下の通りとなる。
JUnitの実行結果

要点まとめ

  • 指定したメソッドで指定した例外をスローするには、MockitoライブラリのdoThrowメソッドを利用する。