KotlinとJUNIT4でControllerテストを作成

## 環境
言語：Kotlin（フレームワーク：spring）
テストフレームワーク：JUNIT4
モックフレームワーク：mockito

## テスト対象のControllerクラス

今回は、【項番・動物名・画像】のデータを出力する画面を考える。
下記コントローラではサービスから受け取ったデータとともに画面を返却しています。

```kotlin:例：動物一覧画面用コントローラ
package jp.com.***zoo.controller.animal.animalList.view

import jp.com.***zoo.service.animal.animalList.AnimalListService
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping

/**
 * 動物一覧画面用Controllerクラス
 */
@Controller
class AnimalListController(private val animalListService: AnimalListService) {
    /**
     * 動物一覧画面用画面を表示
     * @param model: 画面用オブジェクト
     * @return 動物名一覧画面
     */
    @GetMapping("/animal/animal_list/")
    fun init(model: Model): String {
        // 動物リストをモデルに詰める
        model.addAttribute("animalListViewDto", animalListService.getAnimalList())

        // Viewを返却
        return "animal/animalList/animal_list"
    }
}

```



## Controllerテストクラス

```kotlin:例
package jp.com.zoo.controller.animal.animalList.view

import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.mock

import jp.com.zoo.dto.AnimalDto

import jp.com.zoo.controller.animal.animalList.view.dto.animalListViewDto
import jp.com.zoo.service.animal.animalList.animalListService
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.ResultActionsDsl
import org.springframework.test.web.servlet.get
import org.springframework.test.web.servlet.setup.MockMvcBuilders

// 設定ファイルの読み込み（この場合 application-test.properties が読み込まれる）
@ActiveProfiles(value = ["test"]) 
class AnimalListControllerTest {
    // コントローラクラスの動作検証を可能にする
    private lateinit var mockMvc: MockMvc

    // MockMvcのリクエスト結果に対し、期待値Actionを適用できる
    private lateinit var result: ResultActionsDsl

    // Serviceクラスのモック化
    // private val animalListService: AnimalListService = mock() でも良い
    private val animalListService = mock<AnimalListService>()

    // テスト対象のControllerクラス
    private val controller = AnimalListController(
        animalListService
    )

    @BeforeEach
    fun setUp() {
        // MockMVCのインスタンス生成
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
    }

    @Nested
    @DisplayName("init")
    inner class Test01 {

        @Nested
        @DisplayName("正常系")
        inner class Test0101 {
            // 期待値テンプレート
            private val expectedTemplate = AnimalListViewDto(
                mWorkplaceList = mutableListOf(
                    AnimalDto(
                        id = 1,
                        name = "ライオン",
                        image = "/image/animal/lion.png",
                    ),
                    AnimalDto(
                        id = 2,
                        name = "ゾウ",
                        image = "/image/animal/elephant.png",
                    ),
                    AnimalDto(
                        id = 3,
                        name = "パンダ",
                        image = "/image/animal/panda.png",
                    ),
                )
            )

            @Test
            @DisplayName("動物リストを取得できること")
            fun test01() {
                // 期待値
                val expected = expectedTemplate.copy()

                // モック化したServiceメソッド呼び出し
                doReturn(expected).`when`(animalListService).getAnimalList()

                // Controllerの呼び出し
                result = mockMvc.get("/anmal/animal_list/")
                result.andExpect {
                    status { isOk() }
                    view { name("animal/animalList/animal_list") }
                    model { attribute("animalListViewDto", expected) }
                }
            }
        }
    }
}

```