❇️

Spring Boot 3.4.0で追加された MockMvcTester が便利

2024/12/24に公開

Spring Boot 3.4.0 から、AssertJがクラスパスに含まれている場合に MockMvcTester が利用可能になりました。これにより、リクエストとアサーションを流れるように記述でき、テストコードが読みやすくなります。

コントローラー例

以下のコントローラーのテストを書きます。

@RestController
@RequestMapping("/api")
class SampleController {

    @GetMapping("/hello")
    fun hello(): ResponseEntity<String> {
        return ResponseEntity.ok()
            .header("X-Custom-Header", "CustomValue") // カスタムヘッダーをテスト
            .body("Hello, World!") // レスポンスボディをテスト
    }
}

テストコード

Spring Boot 3.4.0 から、以下のように書くことができます。
assertThat で検証したい内容ごとにテストが書けるので「何をテストしているのか」が読みやすいですね。

import ...

@WebMvcTest(SampleController::class)
class SampleControllerTest {

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Test
    fun `hello endpoint should return Hello, World! and custom header`() {
        val result = MockMvcTester(mockMvc)
            .performGet("/api/hello") // GETリクエストを実行
            .expectStatus().isOk      // HTTPステータス200を確認
            .expectBody<String>()     // レスポンスボディを取得
            .returnResult()

        // レスポンスヘッダーの検証
        assertThat(result.responseHeaders["X-Custom-Header"])
            .containsExactly("CustomValue")

        // レスポンスボディの検証
        assertThat(result.response).isEqualTo("Hello, World!")
    }
}

以前は以下のような andExpect() を利用した書き方でした。andExpectの引数に色々と処理を書かねばならず、少し読みづらいコードになってしまいがちでした。

import ...

@WebMvcTest(SampleController::class)
class SampleControllerTest {

    @Autowired
    private lateinit var mockMvc: MockMvc

    @Test
    fun `hello endpoint should return Hello, World! and custom header`() {
        mockMvc.perform(get("/api/hello"))
            .andExpect(status().isOk) // HTTPステータス200を確認
            .andExpect(content().string("Hello, World!")) // レスポンスボディを確認
            .andExpect(header().string("X-Custom-Header", "CustomValue")) // レスポンスヘッダーを確認
    }
}

Discussion