I'm setting up an unit test to ensure that controller method's path variable javax constraints are working as expected with all the required dependencies.
Controller class :
@RestController
@RequestMapping("users")
@Validated
@Slf4j
public class UserSearchController
@GetMapping(value = "/search/{phone}", produces = {"application/json"})
public Mono<ResponseEntity<SearchResult>> searchUsersByPhoneNumber(@PathVariable("phone")
@NotBlank(message = "Number must not be empty")
@Pattern(regexp = "^\\+44\\d{10}$", message = "Invalid phone number. Must be in E.164 format.")
String phone) {
return service.searchByPhoneNumber(phone)
.map(ResponseEntity::ok);
}
}
Test Class :
@ExtendWith(MockitoExtension.class)
public class UserSearchControllerTest {
private MockMvc mockMvc;
@InjectMocks
private UserSearchController userSearchController;
@BeforeEach
public void setup() {
JacksonTester.initFields(this, new ObjectMapper());
mockMvc = MockMvcBuilders.standaloneSetup(userSearchController)
.setControllerAdvice(new RestResponseEntityExceptionHandler())
.build();
}
@Test
public void testSearchByPhoneNumber_InvalidInput_ReturnsBadRequest() throws Exception {
String INVALID_PHONE_NUMBER = "1234567890";
mockMvc.perform(MockMvcRequestBuilders.get("/users/search/{phone}", INVALID_PHONE_NUMBER))
.andExpect(MockMvcResultMatchers.status().isBadRequest());
}
}
RestResponseEntityExceptionHandler
is configured to handle exceptions thrown by the controller.
@ControllerAdvice
@Slf4j
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {ConstraintViolationException.class})
protected ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex, WebRequest request) {
// returning error response
}
This setup is working as expected and constraints are validated correctly in case phone
path variable is not in the expected format. However, unit test is not working as expected, it fails the validation and starting to execute the searchUsersByPhoneNumber
without throwing the exception and end up giving a null pointer exception for service.searchByPhoneNumber(phone)
line. What might be causing this?