Spring Boot + Kotlin でRESTアプリ作成ハンズオン4

前回↓

https://qiita.com/tseno/items/1b96c1845795232e15ec

次回↓

https://qiita.com/tseno/items/b61e9dd284acd5d5b216

# 4. JUnitで単体テストを行う【基礎編】

## 4-1. テストの種類

### 手動テスト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/78ff214f-058c-ca51-4e19-562864c8210b.png)


### JUnitを使用した自動テスト

- Controllerクラスのテストの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/35605a67-6c7d-55e2-7c82-ccc8684dec8a.png)



- Serviceクラスのテストの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/7e5abb31-5b3b-450c-1481-a02df70e2725.png)

## 4-2. 今回作成するテスト

- 前回までに作成したTodoリストのアプリの構造

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/33c491da-7709-dc84-29f8-799e3b7f0a86.png)

- テストは、Controllerクラスが対象になります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/6490cb80-7d48-6da7-59f3-7ffaaf7726bb.png)

## 4-3. HelloControllerテストコードの作成

- テスト対象コード

```kotlin:HelloController.kt
package com.example.demo

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class HelloController {

    @GetMapping("/hello")
    fun getHello(): String {
        return "Hello World!"
    }
}
```

- テストで確認したいこと
    - `/hello` を呼び出した時、`Hello World!` がステータスコード `200 OK` で返却されること。

### テストの作成方法

- ソース上で右クリック、Genereteをクリックして下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/59dfee62-6232-ab54-18e9-400633b9172f.png)

- Testをクリックして下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/a2ab6360-bacd-22d2-20ee-8bbb114ca297.png)

- テストを作成したいメソッドにチェックをつけて、OKボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/e15622cb-b4a9-542f-fdec-58e5ab1f77ac.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/7ab5d4ad-cbb0-7aa1-397d-699ad676ee27.png)

### テストコード
- `@ExtendWith(SpringExtension::class)` は、Springの機能を使ったテストを実行するための拡張機能が読み込まれます
- `@WebMvcTest(controllers = [HelloController::class])` コントローラ層のみのユニットテストを実行します。

```kotlin:HelloControllerTest.kt
package com.example.demo

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status


@ExtendWith(SpringExtension::class)
@WebMvcTest(controllers = [HelloController::class])
class HelloControllerTest {

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Test
    fun getHello() {
        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk)
                .andExpect(content().string("Hello World!"))
    }
}
```

## 4-4. テストの実行

- 緑の▶をクリックしてテストを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/3ac93fa1-75eb-46fd-e477-df31c1b1ca76.png)

- テストを失敗させてみます（確認後、ソースは元に戻しておいてください。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/ae059806-d5d1-6519-230a-cf09469630d0.png)

## 4-5. 404 Not Foundのテスト

- メソッドを日本語で書くと、結果一覧に日本語でテスト内容が出るのでわかりやすいです

```kotlin:HelloControllerTest.kt（一部）
    @Test
    fun 存在しないエンドポイントではNotFoundが出る() {
        mockMvc.perform(get("/helloworld"))  // 存在しないエンドポイント
                .andExpect(status().isNotFound)
    }
```

- 実行結果、文字化けしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/7eacaca9-735c-c2bb-74d8-7ce775520024.png)



## 4-6. 文字化けを直す

- Help→Edit Custom VM Options

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/8c31740f-66ea-e6d7-1e7b-1251c8d60767.png)

- `-Dfile.encoding=UTF-8` を追加して保存。
- Intellij を再起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/bed2e757-a526-592d-edaf-75f5940cb276.png)


- テスト再実行すると、直りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/c843c2dc-34f7-42ac-8c44-6c8b7407b002.png)

おわり