1

Following the advice from here Spring Boot Remove Whitelabel Error Page I created a custom error controller to return custom error response in json format which looks like

@RestController
public class CustomErrorController implements ErrorController {

private static final String PATH = "/error";

@Value("${spring.debug:false}")
private boolean debug;

@Autowired
private ErrorAttributes errorAttributes;

  @RequestMapping(value = PATH)
  ErrorJson error(HttpServletRequest request, HttpServletResponse response) {
    return new ErrorJson(response.getStatus(), getErrorAttributes(request, debug));
  }

  private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
    RequestAttributes requestAttributes = new ServletRequestAttributes(request);
    return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
  }

  @Override
  public String getErrorPath() {
    return PATH;
  }

}

Where CustomErrorController implements ErrorController and ErrorJson is just a simple class to format json error response.

Now I am trying to write a Test, to test if a nonexistent enpoint is hit the CustomErrorController handles it and returns a 404 with json response like:

{
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "timeStamp": "Thu Jun 29 14:55:44 PDT 2017",
  "trace": null
}

My test currently looks like

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CustomErrorControllerTest {

    @Autowired
    private MockMvc mockMvc;


    @Test
    public void invalidURLGet() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/foo"))
                .andExpect(status().is(404))
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andReturn();

    }


}

I get the error response with status 404 but the content body is null, with MockHttpServletResponse as:

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {X-Application-Context=[application:development:-1]}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

So, I have 2 questions:

  1. Why is the content body is null. Is MockMvc not able to find the CustomErrorController.
  2. Am I testing the error behaviour incorrectly. If so how can I test the custom error response?
harshs08
  • 700
  • 10
  • 29

1 Answers1

1

You may get further with a TestRestTemplate instead. This will allow you to not only make the appropriate URI calls, but also give you the chance to serialize your response into the actual object it's coming back as to verify that your body and other elements are actually present.

Brief example:

// Elsewhere...
@Autowired
private TestRestTemplate template;

// In your tests...
ErrorJson result = template.getForObject("/error", ErrorJson.class);

// Inspect the result!
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • Tried using `TestRestTemplate` but getting the following error now. *************************** APPLICATION FAILED TO START *************************** Description: The Tomcat connector configured to listen on port 0 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connector's configuration, identify and stop any process that's listening on port 0, or configure this application to listen on another port. – harshs08 Jun 29 '17 at 22:56
  • So...you sure you set a random port for your tests? How to do that is provided in the link I gave you. – Makoto Jun 29 '17 at 22:57
  • Yes using `@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)` – harshs08 Jun 29 '17 at 22:57