2021/01/27

AtCoder

その他

Spring Boot のテストで死ぬほどハマった。

Spring Boot を使っているとき、ある Controller と必要な Bean だけ立ち上げてテストしたいということがよくある。普通に Controller を初期化してもよいが、より結合テスト寄りのことができると嬉しいので MockMvc を使ってテストがしたくなる。MockMvc を使える状態にする王道の方法は @WebMvcTest をつけることだが、これをすると読み込みたくない Configuration まで取り込まれた挙げ句、初期化に失敗したりして怒られる。残念ながら WebMvcTest の exclude... みたいなオプションは Configuration を exclude するのには使えない。それどころか、どうも Spring 周りのテストでは読み込まれる予定の Configuration を設定で除外することがそもそもできないように見える。

なので @WebMvcTest を使うのは諦めて @SpringBootTest で読み込まれるクラスを絞りまくることにする。MockMvc を使いたい場合は @AutoConfigureMockMvc をつければよい。これで解決かと思いきや、クラスを絞りすぎたせいで、mockMvc で API を叩いた時にレスポンスを JSONシリアライズしたりしてくれるやつ (ProjectingJackson2HttpMessageConverter) もいないため、あらゆるレスポンスが 400 だか 500 だかになってしまう。これを解決するためには @EnableWebMvc をつけると良い。必要なクラスを Bean として作ってくれる。@WebMvcTest では読み込まれていた Configuration が @EnableWebMvc では読み込まれないのは直感に反する……