13

I am using MockMVC to test my controller.

I have the following controller:

public class A{

    ...

    @RequestMapping("/get")
    public List<ADTO> get(@RequestParam(defaultValue = "15", required = false) Integer limit) throws IOException {
        if(limit <= 0 || limit >= 50){
            throw new IllegalArgumentException();
        }
        ...
        return aDTOs;
    }

}

And my current test looks like this:

@Test
public void testGetAllLimit0() throws Exception {
    mockMvc.perform(get("/A/get")
            .param("limit","0")
            )
            .andDo(print())
            .andExpect(...);
}

I am instantiating MockMVC with this:

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

How can I take care of that exception thrown in my controller?

Later Edit:

I'm not sure what happened in my code recently but it passes the test:

@Test
public void testGetAllLimit0() throws Exception {
    mockMvc.perform(get("/A/get")
            .param("limit","0")
            )
            .andDo(print())
            .andExpect(status().is(500));
}

It still passes if I replace is(500) with isOk(). And this is not good, I should check somehow for that exception.

If I run a gradle build I get this:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException
tzortzik
  • 4,993
  • 9
  • 57
  • 88
  • What kind of HTTP response do you expect to get when a controller throws such an exception? I'd expect an error 500. If that's what you expect, that's what your test should verify. If you expect another error (an error 400 would be more appropriate), then test that you get such an error in the test, and fix the code until the test passes. – JB Nizet Apr 12 '15 at 09:37
  • I already tried to expect 500 error but it doesn't work because it stops the execution when the error is thrown. – tzortzik Apr 12 '15 at 09:51
  • I updated my initial post. Something strange happened. – tzortzik Apr 12 '15 at 09:58

2 Answers2

7

Did you try to use a custom ExceptionHandler like here? : https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

If you do so you can return custom HTTP response codes and verify them in your test.

mrkernelpanic
  • 4,268
  • 4
  • 28
  • 52
3

Easier way is to inject @ExceptionHandler into your Spring Test Context or it throws exception right in MockMvc.perform() just before .andExpect().

@ContextConfiguration(classes = { My_ExceptionHandler_AreHere.class })
@AutoConfigureMockMvc
public class Test {
    @Autowired
    private MockMvc mvc;

    @Test
    public void test() {
        RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/update")
                .param("branchId", "13000")
                .param("triggerId", "1");
        MvcResult mvcResult = mvc.perform(requestBuilder)
                .andExpect(MockMvcResultMatchers.status().is4xxClientError())
                .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(__ -> Assert.assertThat(
                        __.getResolvedException(),
                        CoreMatchers.instanceOf(SecurityException.class)))
                .andReturn();
}

That way MvcResult.getResolvedException() holds @Controller's exception!

gavenkoa
  • 45,285
  • 19
  • 251
  • 303