java 使用 MockMvc 测试重定向 URL 的 HTTP 状态代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41142871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:42:45  来源:igfitidea点击:

Test HTTP status code of redirected URL with MockMvc

javaspring-mvcspring-bootmockmvcspring-mvc-test

提问by Ben

I want to test the login process in a Spring Boot Application using MockMvc. After the successful login, the user gets redirected to /home. To test this, I use:

我想使用 MockMvc 在 Spring Boot 应用程序中测试登录过程。成功登录后,用户将被重定向到 /home。为了测试这一点,我使用:

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

This test delivers the expected results.

该测试提供了预期的结果。

In addition, I must test the HTTP status code of the redirected page (/home). Lets say the /home-page returns an HTTP 500 internal Server error, I need to be able to test this.

另外,我必须测试重定向页面(/home)的HTTP状态码。假设 /home-page 返回 HTTP 500 内部服务器错误,我需要能够对此进行测试。

I tried the following:

我尝试了以下方法:

@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());
}

Instead if getting a 200 or a 500 (in case of an error), I get the status code 302.

相反,如果得到 200 或 500(在出现错误的情况下),我会得到状态代码 302。

Is there any way to correctly test the HTTP status code when following a redirect-URL?

在跟踪重定向 URL 时,是否有任何方法可以正确测试 HTTP 状态代码?

Thanks and best regards

谢谢和最好的问候

采纳答案by Nathan Russell

First, I would split your test into 2 separate tests, because you are testing 2 quite different scenarios:

首先,我会将您的测试分成 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());
}

Your first test is that of the successful login scenario.

您的第一个测试是成功登录场景。

The second test, as you've worded it in your question, is that where the home page (assuming a controller) returns a HTTP 500.
To get to the home page, you still need to login - it's not the act of logging on that generates the error, its the controller itself once you've logged on.
To make the controller return a HTTP 500 you are going to need to simulate some error. Without seeing your controller, I can only guess there is some service that is injected in. In your test you should be able to provide a mock of that, and then configure the mock to throw an exception.

第二个测试,正如您在问题中所说的,是主页(假设有控制器)返回 HTTP 500 的地方。
要进入主页,您仍然需要登录 - 这不是登录的行为一旦您登录,就会产生错误,它是控制器本身。
要使控制器返回 HTTP 500,您需要模拟一些错误。在没有看到您的控制器的情况下,我只能猜测注入了一些服务。在您的测试中,您应该能够提供一个模拟,然后配置模拟以抛出异常。

You should be able to inject a mock something like this:

你应该能够注入这样的模拟:

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

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private YourService yourService;

And then within your test do something like the following (I'm using the BDD methods of mockito):

然后在您的测试中执行以下操作(我使用的是 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());
}