Answer the question
In order to leave comments, you need to log in
How to test the controller along with error trapping through ControllerAdvice?
Hello. I use spring 5 along with spring boot 5, junit 5, mvc. You need to test the controller along with a class annotated with the @ControllerAdvice annotation. My class with tests:
@WebMvcTest(controllers = ExportToMsExcelController.class, secure = false)
class ExportToMsExcelControllerTests {
private static final String EXPORT_RESOURCE_1_URL = "/resource1/list/ms-excel"; // URL для rest-запроса по выгрузки в эксель
private static final String CONTENT_TYPE = "application/vnd.ms-excel";
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private CreateXLSXDocumentService createXLSXDocumentService;
/**
* Тест выгрузки в файл в формате MS Excel,
* входные данные: нет (search-строка не указана),
* выходные данные: ошибка 500, непустой текст ошибки,
* особенности: внутренний сервис вернул null
*
* @throws Exception любые исключительные ситуации
*/
@Test
void exportTable_noSearchStringAndInternalServiceReturnsNull_HttpCode500AndErrorMessageReturned() throws Exception {
given(createXLSXDocumentService.createXLSXDocument(anyMap()))
.willReturn(null);
final MvcResult mvcResult = mockMvc.perform(
get(EXPORT_RESOURCE_1_URL)
.accept(CONTENT_TYPE)
)
.andDo(print())
.andExpect(status().isInternalServerError())
.andReturn();
final String errorMessage = mvcResult.getResponse().getErrorMessage();
assertNotNull(errorMessage, "errorMessage is null");
assertTrue(errorMessage.length() > 0, "errorMessage.length() <= 0");
}
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
private final static Logger logger = LogManager.getLogger(RestExceptionHandler.class);
//реализации методов абстрактного класса
@ExceptionHandler({ NullPointerException.class })
public ResponseEntity<Object> handleNullPointerException(NullPointerException ex, WebRequest request) {
logger.error(ex.getLocalizedMessage(), ex);
return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage(), ex, null, new ArrayList<> (Arrays.asList(ex.getStackTrace()))));
}
@ExceptionHandler({ IllegalArgumentException.class })
public ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
logger.error(ex.getLocalizedMessage(), ex);
return buildResponseEntity( new ApiError(HttpStatus.BAD_REQUEST, ex.getMessage(), ex, null, new ArrayList<>(Arrays.asList(ex.getStackTrace()))) );
}
@ExceptionHandler({ RuntimeException.class })
public ResponseEntity<Object> handleRuntimeException(RuntimeException ex, WebRequest request) {
logger.error(ex.getLocalizedMessage(), ex);
return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage(), ex, null, new ArrayList<> (Arrays.asList(ex.getStackTrace()))));
}
@ExceptionHandler({ javax.validation.ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolationException(javax.validation.ConstraintViolationException ex, WebRequest request) {
logger.error(ex.getMessage(), ex);
String message = ex.getMessage();
return buildResponseEntity(new ApiError(HttpStatus.BAD_REQUEST, message, ex, null, new ArrayList<> (Arrays.asList(ex.getStackTrace()))));
}
private ResponseEntity<Object> buildResponseEntity(ApiError apiError) {
return new ResponseEntity<>(apiError, apiError.getStatus());
}
}
Answer the question
In order to leave comments, you need to log in
@WebMvcTest implements the so-called. testing by layers of a Spring application, namely, it does not load extra beans and configurations that are not needed in this type of test. Because of this, @ControllerAdvice are not automatically loaded into the context.
There are two solutions to choose from: a normal integration test (@SpringBootTest, etc.) with a call to the controller via RestTemplate or using MockMvcBuilder to configure MockMvc (rather than injection via @Autowired), in which you can specify which advises are needed for this test.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question