web-dev-qa-db-ja.com

MockMvcを使用してリダイレクトされたURLのHTTPステータスコードをテストします

MockMvcを使用してSpringBootアプリケーションでログインプロセスをテストしたいと思います。ログインに成功すると、ユーザーは/ homeにリダイレクトされます。これをテストするために、私は使用します:

@Test
public void testLogin() throws Exception {
    RequestBuilder requestBuilder = formLogin().user("[email protected]").password("test");
    mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().isFound());
}

このテストは期待される結果をもたらします。

さらに、リダイレクトされたページ(/ home)のHTTPステータスコードをテストする必要があります。/home-pageがHTTP500内部サーバーエラーを返したとしましょう。これをテストできる必要があります。

私は以下を試しました:

@Test
public void testLogin() throws Exception {
    RequestBuilder requestBuilder = formLogin().user("[email protected]").password("test");
    mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().isFound());
    mockMvc.perform(get("/home").with(csrf())).andExpect(status().isOk());
}

代わりに、200または500(エラーの場合)を取得すると、ステータスコード302が取得されます。

リダイレクトURLをたどるときにHTTPステータスコードを正しくテストする方法はありますか?

よろしくお願いします

7
Ben

まず、2つのまったく異なるシナリオをテストしているため、テストを2つの別々のテストに分割します。

@Test
public void testSuccessfulLogin() throws Exception {
    RequestBuilder requestBuilder = formLogin().user("[email protected]").password("test");
    mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().isFound());
}

@Test
public void testHomepageThrows500() throws Exception {

    // configure a mock service in the controller to throw an exception

    RequestBuilder requestBuilder = formLogin().user("[email protected]").password("test");
    mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().is5xxServerError());
}

最初のテストは、成功したログインシナリオのテストです。

2番目のテストは、質問で述べたように、ホームページ(コントローラーを想定)がHTTP500を返す場所です。
ホームページにアクセスするには、ログインする必要があります。エラーが発生するのはログオンの行為ではなく、ログオンした後のコントローラー自体です。
コントローラーがHTTP500を返すようにするには、エラーをシミュレートする必要があります。コントローラーを見なくても、注入されたサービスがあると推測できます。テストでは、そのモックを提供し、例外をスローするようにモックを構成できるはずです。

次のようなモックを注入できるはずです。

@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(HomeController.class)
public class HomeControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private YourService yourService;

そして、テスト内で次のようなことを行います(私はmockitoのBDDメソッドを使用しています):

@Test
public void testHomepageThrows500() throws Exception {

    given(yourService.someMethod()).willThrow(new Exception("something bad happened");

    RequestBuilder requestBuilder = formLogin().user("[email protected]").password("test");
    mockMvc.perform(requestBuilder).andExpect(redirectedUrl("/home")).andExpect(status().is5xxServerError());
}
7
Nathan Russell