MockHttpServletRequestでcontrollerのテストする(1)

エキサイト株式会社の中です。

Java Spring Bootでcontrollerのテストをする方法を説明します。

ユースケース

  1. controllerのテストをする。
  2. Cookieを設定する

題材

コード例

@GetMapping("cookie")
public String showCookies(
        @CookieValue(name = "naka", required = false) Cookie cookieNaka
) {
    return Optional
            .ofNullable(cookieNaka)
            .map(cookie -> cookie.getValue())
            .orElseThrow(BadRequestException::new);
}

入力例

実際のTestクラス。

@ExtendWith(MockitoExtension.class)
class TestControllerTest {
    @InjectMocks
    private TestController testController;

    private MockMvc mockMvc;

    @BeforeEach
    public void before() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(this.testController).build();
    }

    @Test
    public void getShowCookies() {
        try {
            MockHttpServletRequestBuilder getRequest = MockMvcRequestBuilders.get("/cookie");
            final String contentAsString = this.mockMvc.perform(getRequest.with(request -> {
                Cookie[] cookies = new Cookie[] {
                        new Cookie("hoge", "hoge"),
                        new Cookie("abe", "abe"),
                        new Cookie("naka", "sho")
                };
                request.setCookies(cookies);
                request.setParameter("name", "");

                return request;
            }))
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andReturn().getResponse().getContentAsString();

            assertEquals("sho", contentAsString);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

出力例

テスト結果のコンソール。

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /cookie
       Parameters = {name=[hogehoge]}
          Headers = [Cookie:"hoge=hoge; abe=abe; naka=sho"]
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.controller.TestController
           Method = com.controller.TestController#showCookies(Cookie)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"text/plain;charset=ISO-8859-1", Content-Length:"3"]
     Content type = text/plain;charset=ISO-8859-1
             Body = sho
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
BUILD SUCCESSFUL in 2s
13 actionable tasks: 1 executed, 12 up-to-date
23:25:25: Task execution finished ':api:test --tests "com.controller.TestControllerTest.getShowCookies"'.

条件

  • Cookieに設定する

解説

@BeforeEach
public void before() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(this.testController).build();
}

apiの受け口をmockで用意します。

MockHttpServletRequestBuilder getRequest = MockMvcRequestBuilders.get("/cookie");

受け口のリクエストのmockを作成します。

final String contentAsString = this.mockMvc.perform(getRequest.with(request -> {
    Cookie[] cookies = new Cookie[] {
            new Cookie("hoge", "hoge"),
            new Cookie("abe", "abe"),
            new Cookie("naka", "sho")
    };
    request.setCookies(cookies);
    request.setParameter("name", "hogehoge");

    return request;
}))

受け口の細かい設定を追加します。 クッキーやパラメータを設定することができます。

.andDo(MockMvcResultHandlers.print())

リクエストの詳細をコンソールに出力します。

.andExpect(MockMvcResultMatchers.status().isOk())

レスポンスステータス200であることをテストします。

.andReturn().getResponse().getContentAsString();

レスポンスを文字列で受け取ります。

実際のテストについて

controllerのテストは上記をみていただけたら分かる通り、かなり設定が複雑で大変です。

プロジェクトの規模によりますがUTは行わず、ITa以降からのテストで十分確認が取れると思いますので、参考程度にみていただけると幸いです。