Handling MethodArgumentNotValidException in Junit testcase?
Andrew Henderson
I am using spring MVC testing: In my test case, I am passing an invalid Bar object(age with zero). The MethodArgumentNotValidException is being thrown, but it is nested inside a NestedServletException. Is there anyway to throw the MethodArgumentNotValidException exception from the controller through an existing/custom HandlerExceptionResolver, so that my current test case checkHit2 passes?
Controller:
@RequestMapping(value="/test", method = RequestMethod.POST, headers="Accept=application/json") @ResponseBody public Bar getTables(@Valid @RequestBody Bar id) { return id; }TestCase
@Before
public void setUp() { mockMvc = standaloneSetup(excelFileUploader).setHandlerExceptionResolvers(new SimpleMappingExceptionResolver()).build();
}
@Test(expected=MethodArgumentNotValidException.class) public void checkHit2() throws Exception { Bar b = new Bar(0, "Sfd"); mockMvc.perform( post("/excel/tablesDetail").contentType( MediaType.APPLICATION_JSON).content( TestUtil.convertObjectToJsonBytes(b)));Bar
public class Bar { @JsonProperty("age") @Min(value =1) private int age;
public Bar(int age, String name) { super(); this.age = age; this.name = name; }
...
}Junit output
java.lang.Exception: Unexpected exception,
expected<org.springframework.web.bind.MethodArgumentNotValidException> but
was<org.springframework.web.util.NestedServletException> 4 1 Answer
I had similar issue and I fixed it extending my exception class from NestedServletException. For example:
@RequestMapping(value = "/updateForm/{roleID}", method = RequestMethod.GET) public String updateForm(@PathVariable Long roleID, Model model, HttpSession session) throws ElementNotFoundException { Role role = roleService.findOne(roleID); if (role == null) { throw new ElementNotFoundException("Role"); } ...
}And my exception looks like:
public class ElementNotFoundException extends NestedServletException { private static final long serialVersionUID = 2689075086409560459L; private String typeElement; public ElementNotFoundException(String typeElement) { super(typeElement); this.typeElement = typeElement; } public String getTypeElement() { return typeElement; }
}So my test is:
@Test(expected = ElementNotFoundException.class)
public void updateForm_elementNotFound_Test() throws Exception { String roleID = "1"; Mockito.when(roleService.findOne(Long.valueOf(roleID))).thenReturn(null); mockMvc.perform(get("/role/updateForm/" + roleID)).andExpect(status().isOk()).andExpect(view().name("exception/elementNotFound"));
}