I am working on a project with Spring microservices (modules) and I want to test my REST endpoint using MockMvc
. My testing works fine for cases where the request is valid but it is not working when requesting a url that is invalid. By not working I mean my custom exception handler (@ControllerAdvice
) does not get called, the exception gets thrown and the test fails.
My exception handler and testing class are implemented in different modules.
common-module (ExceptionHandler)
@ControllerAdvice
public class CoreExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorMessageDTO> handleException(Exception ex, HttpServletRequest request) {
// Getting servlet request URL
String uri = request.getRequestURI();
HttpStatus a;
ErrorMessageDTO errorMessage;
if (ex instanceof CoreException) {
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else {
errorMessage = new ErrorMessageDTO(ex, uri);
...
}
return new ResponseEntity<ErrorMessageDTO>(errorMessage, a);
}
}
country-module
This is where my REST endpoint and Testing class are implemented. The common module dependency is included in this module's pom.xml and the packages are scanned through the main class.
CountryApplication.java
@EnableCaching
@EnableDiscoveryClient
@EnableAspectJAutoProxy
@SpringBootApplication(scanBasePackages = {
"com.something1.something2.something3.common.exception",
"com.something1.something2.something3.common.util.logged",
"com.something1.something2.something3.country"
})
public class CountryApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(CountryApplication.class, args);
}
...
}
CountryService.java
This is a method in my Service class.
@GetMapping("/{id:\\d+}")
public CountryDTO getCountryById(@PathVariable("id") Integer id) throws CoreException {
Country countryEntity = this.countryRepository.findOne(id);
// requesting for id that does not exist
if (countryEntity == null) {
throw new CoreException(CoreError.ENTITY_NOT_FOUND);
}
return this.countryMapper.daoToDto(countryEntity);
}
CountryServiceTest.java
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
public class CountryServiceTest {
...
@Autowired
private MockMvc mockMvc;
@Test
public void getByIdTest() throws Exception {
// Get by id exists
mockMvc.perform(get("/2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andDo(print());
// Get by id not exists. NOT WORKING
mockMvc.perform(get("/100000"))
.andExpect(status().isNotFound())
.andExpect(content().contentType(contentType));
}
}
As I described above, the problem is that at the second request of the test method, the CoreExceptionHandler
does not get called and the test fails throwing a:
NestedServletException: Request processing failed; nested exception is com.something1.something2.something3.common.exception.CoreException
.
The dependency for the common module is well configured (at least when I am deploying in non-test mode) since I am using it for other things too, plus the ExceptionHandler gets called when I am not testing.
Another strange thing is that when I am deploying my Test, Spring Boot's logs show that the CoreExceptionHandler
gets detected. This is the line. Detected @ExceptionHandler methods in coreExceptionHandler
Aucun commentaire:
Enregistrer un commentaire