'How to write Unit Test for below Exception Handler method using mockito?
@ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex, WebRequest request) {
StringBuilder messageBuilder = new StringBuilder("Validation failed for: ");
ex.getConstraintViolations()
.stream()
.forEach(v -> messageBuilder
.append("property: [" + v.getPropertyPath() + "], value: [" + v.getInvalidValue() + "], constraint: [" + v.getMessage() + "]"));
return new ResponseEntity<>(responseBuilder
.createErrorResponse(INVALID_PARAMETER,
messageBuilder.toString()), getHeaders(), BAD_REQUEST);
}
I want to test this @ControllerAdvice method
Solution 1:[1]
If you just want to test the method it suffices to create an instance of ConstraintViolationException
(your input) and check the output of the handleConstraintViolation
method applied to it.
You can do somthing like this:
ConstraintViolationException exception = mock(ConstraintViolationException.class);
WebRequest webRequest = mock(WebRequest.class);
YourControllerAdvice controllerAdvice = new YourControllerAdvice();
Set<ConstraintViolation<?>> violations = new HashSet<>();
ConstraintViolation mockedViolation = mock(ConstraintViolation.class);
given(mockedViolation.getPropertyPath()).willReturn("something");
// mock answer to other properties of mockedViolations
...
violations.add(mockedViolation);
given(exception.getContraintViolations()).willReturn(violations);
ResponseEntity<Object> response = controllerAdvice.handleContraintViolation(exception, webRequest);
assertThat(response.getStatusCode(), is(HttpStatus.BAD_REQUEST));
plus maybe other assertions on the response body.
However it can be difficult to know how all the different ConstraintViolationException
instances thrown by spring might look like.
I would instead suggest that you look at MockMvc, which is part of spring-boot-starter-test
. In this way you can test that the exception handler is used as expected and you can verify the ResponseEntity
both in the case of constraint violations or not.
@WebMvcTest(YourController.class)
public class YourControllerMvcTest {
@Autowired
private MockMvc mvc;
@Test
public void constraintViolationReturnsBadRequest() throws Exception {
// Instantiate the DTO that YourController takes in the POST request
// with an appropriate contraint violation
InputDto invalidInputDto = new InputDto("bad data");
MvcResult result = mvc.perform(post("/yourcontrollerurl")
.content(invalidInputDto)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest());
// assert that the error message is as expected
assertThat(result.getResponse().getContentAsString(), containsString("default message [must match"));
}
}
MockMvc has also nice json support so that one can add:
.andExpect(MockMvcResultMatchers.jsonPath("$.field").value("expected value"))
instead of the verifying the response as a string.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | scre_www |