使用MockMvc和Spring REST文档时重新使用Spring引导ErrorAttributes

问题描述 投票:1回答:2

我写的测试为其标注有AuthenticationException抛出一个自定义异常(@ResponseStatus(value = HttpStatus.BAD_REQUEST)在我的情况)控制器

调用,使用抛出异常的终点即卷曲工作正常,我得到如下所示的例子预期的结果:

{
  "timestamp": 1494185397677,
  "status": 400,
  "error": "Bad Request",
  "exception": "com.example.exception.AuthenticationException",
  "message": "These are not the credentials you are looking for",
  "path": "/status/throw/2"
}

当我写这有一个的Mockito测试,使用willThrow()我没有得到任何春启动生成输出,但同样标注的我异常类的响应代码。

下面是我的测试:

@Test
public void throwsShouldShowResponseBody() throws Exception {
    given(this.service.getAccStatus())
            .willThrow(AuthenticationException.class);

    this.mvc.perform(get("/status/throw/2"))
            .andExpect(status().isBadRequest())
            .andDo(document("bad-credentials"));
}

寻找类似的问题看来,这可能是由MockMvc不遵守,我认为春天开机使用推向/错误,但我想问的是,如果有反正我可以做这个工作,所以我没有写@ControllerAdvice类重定向引起类似的东西ErrorAttributes了Spring启动已经提供。我不希望改变这种弹簧引导产生的错误输出。

谢谢 -

spring-boot mockito mockmvc spring-restdocs
2个回答
2
投票

如您所知,这是棘手的使用MockMvc时记录春天启动的错误响应一点点。这是因为春季启动将请求转发到被映射到/errorMockMvc默认不转发处理错误控制。

记录一个错误的响应的一种方式是直接与适当配置的请求调用/error。这里有一个example of this in one of Spring REST Docs' samples

@Test
public void errorExample() throws Exception {
    this.mockMvc
        .perform(get("/error")
            .requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 400)
            .requestAttr(RequestDispatcher.ERROR_REQUEST_URI, "/notes")
            .requestAttr(RequestDispatcher.ERROR_MESSAGE, "The tag 'http://localhost:8080/tags/123' does not exist"))
        .andExpect(status().isBadRequest())
        .andExpect(jsonPath("error", is("Bad Request")))
        .andExpect(jsonPath("timestamp", is(notNullValue())))
        .andExpect(jsonPath("status", is(400)))
        .andExpect(jsonPath("path", is(notNullValue())))
        .andDo(this.documentationHandler.document(
            responseFields(
                fieldWithPath("error").description("The HTTP error that occurred, e.g. `Bad Request`"),
                fieldWithPath("message").description("A description of the cause of the error"),
                fieldWithPath("path").description("The path to which the request was made"),
                fieldWithPath("status").description("The HTTP status code, e.g. `400`"),
                fieldWithPath("timestamp").description("The time, in milliseconds, at which the error occurred"))));
}

它然后used in the resulting documentation来描述公司在其整个API使用的错误响应格式。


0
投票
package com.cts.skynews.springboot.controller;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserControllerTest.class);

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void addNewUser() throws Exception {
        LOGGER.info("START : Inside Spring Boot addUser() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
                + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().isOk()).andExpect(jsonPath("$.signedUp").value("true"));

        LOGGER.info("END : Spring Boot addUser() method of UserController");

    }

    @Test
    public void checkEmailExists() throws Exception {
        LOGGER.info("START : Inside Spring Boot checkEmailExists() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
                + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().isOk()).andExpect(jsonPath("$.emailExists").value("true"))
                .andExpect(jsonPath("$.signedUp").value("false"));

        LOGGER.info("END : Spring Boot checkEmailExists() method of UserController");

    }

    @Test
    public void incorrectEmailFormat() throws Exception {
        LOGGER.info("START : Inside Spring Boot incorrectEmailFormat() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"rgmail.com\"," + "\"password\":\"A123456\","
                + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Email address is invalid"));
        LOGGER.info("END : Spring Boot incorrectEmailFormat() method of UserController");
    }

    @Test
    public void nullName() throws Exception {
        LOGGER.info("START : Inside Spring Boot nullName() method of UserController");

        String USER_DATA = "{\"email\":\"[email protected]\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
                + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Name cannot be empty"));

        LOGGER.info("END : Spring Boot nullName() method of UserController");
    }

    @Test
    public void nullPassword() throws Exception {
        LOGGER.info("START : Inside Spring Boot nullPassword() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Password cannot be empty"));

        LOGGER.info("END : Spring Boot nullPassword() method of UserController");
    }

    @Test
    public void nullEmail() throws Exception {
        LOGGER.info("START : Inside Spring Boot nullEmail() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
                + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Email cannot be empty"));

        LOGGER.info("END : Spring Boot nullEmail() method of UserController");
    }

    @Test
    public void nullStatus() throws Exception {
        LOGGER.info("START : Inside Spring Boot nullEmail() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"password\":\"A123456\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Status cannot be empty"));

        LOGGER.info("END : Spring Boot nullStatus() method of UserController");
    }

    @Test
    public void langugaeNull() throws Exception {
        LOGGER.info("START : Inside Spring Boot langugaeNull() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Language cannot be empty"));

        LOGGER.info("END : Spring Boot langugaeNull() method of UserController");
    }

    @Test
    public void roleNull() throws Exception {
        LOGGER.info("START : Inside Spring Boot roleNull() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\","
                + "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Role cannot be empty"));

        LOGGER.info("END : Spring Boot roleNull() method of UserController");
    }

    @Test
    public void invalidNameLength() throws Exception {
        LOGGER.info("START : Inside Spring Boot invalidNameLength() method of UserController");

        String USER_DATA = "{\"name\":\"KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya "
                + "KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya "
                + "KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya\","
                + "\"email\":\"[email protected]\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
                + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";

        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError())
                .andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Name must be 3 to 80 characters"));

        LOGGER.info("END : Spring Boot invalidNameLength() method of UserController");

    }

    @Test
    public void invalidEmailLength() throws Exception {
        LOGGER.info("START : Inside Spring Boot invalidEmailLength() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\","
                + "\"email\":\"ravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@[email protected]\","
                + "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
                + "\"role\":{\"id\":1}}";

        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError()).andExpect(
                        jsonPath("$.errorMessage").value("Input Validation Failed:Email must be 4 to 80 characters"));

        LOGGER.info("END : Spring Boot invalidEmailLength() method of UserController");

    }

    @Test
    public void incorrectPasswordFormat() throws Exception {
        LOGGER.info("START : Inside Spring Boot incorrectPasswordFormat() method of UserController");

        String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"[email protected]\"," + "\"password\":\"12\","
                + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().is4xxClientError()).andExpect(jsonPath("$.errorMessage")
                        .value("Input Validation Failed:Password must be 6 to 45 characters"));

        LOGGER.info("END : Spring Boot incorrectPasswordFormat() method of UserController");
    }

    @Test
    public void successfullLogin() throws Exception {
        LOGGER.info("START : Inside Spring Boot successfullLogin() method of UserController");

        String USER_DATA = "{\"email\":\"[email protected]\",\"password\":\"A123456\"}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("true"));

        LOGGER.info("END : Spring Boot successfullLogin() method of UserController");
    }

    @Test
    public void invalidEmailForLogin() throws Exception {
        LOGGER.info("START : Inside Spring Boot invalidEmailForLogin() method of UserController");

        String USER_DATA = "{\"email\":\"[email protected]\",\"password\":\"A123456\"}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("false"));

        LOGGER.info("END : Spring Boot invalidEmailForLogin() method of UserController");
    }

    @Test
    public void invalidPasswordForLogin() throws Exception {
        LOGGER.info("START : Inside Spring Boot invalidPasswordForLogin() method of UserController");

        String USER_DATA = "{\"email\":\"[email protected]\",\"password\":\"12345678\"}";
        LOGGER.debug("JSON Object :  {}", USER_DATA);

        mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
                .andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("false"));;

        LOGGER.info("END : Spring Boot invalidPasswordForLogin() method of UserController");
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.