我正在用RestController
测试mockMvc
。我有一个全局RestExceptionHandler
来解决所有异常。在我的RestController
中,我像这样抛出了自定义Exception
RequestValidationException
:
@ApiOperation("Search something")
@RequestMapping(path = "/search", method = RequestMethod.POST)
public CompletableFuture<SomeResponse> search(
@RequestBody @Validated SearchRequest request, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new RequestValidationException(bindingResult);
}
return searchService.search(request);
}
当我传递空请求时,它必须抛出RequestValidationException(bindingResult)
但是当我开始测试时,它们落在我抛出Exception
的地方,而不是解决它。
我尝试这样配置mockMvc
:
@RunWith(SpringRunner.class)
public class SearchControllerTest {
private MockMvc mockMvc;
@InjectMocks
protected SearchController searchController;
@MockBean
private SearchService searchService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(searchController)
.setHandlerExceptionResolvers(getHandlerExceptionResolver())
.build();
}
private HandlerExceptionResolver getHandlerExceptionResolver() {
final StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerSingleton("exceptionHandler", RestExceptionHandler.class);
final WebMvcConfigurationSupport webMvcConfigurationSupport = new WebMvcConfigurationSupport();
webMvcConfigurationSupport.setApplicationContext(applicationContext);
return webMvcConfigurationSupport.handlerExceptionResolver();
}
但是没有帮助。我收到带有消息的Exception
插入的json。
我的RequestValidationExceptionHandler
:
@Component
public class RequestValidationExceptionHandler implements ApiExceptionHandler {
@Override
public ResponseEntity<ApiResponse> process(Throwable throwable) {
RequestValidationException e = (RequestValidationException) throwable;
if (e.getBindingResult() != null) {
return new ResponseEntity<>(ApiResponse.badRequest(e.getBindingResult()), HttpStatus.OK);
}
return new ResponseEntity<>(ApiResponse.badRequest(throwable, ApiResponseCode.BAD_REQUEST), HttpStatus.OK);
}
@Override
public Class<? extends Throwable> getSupportedException() {
return RequestValidationException.class;
}
}
2)我的@ControllerAdvice
:
@Slf4j
@ControllerAdvice
@SuppressWarnings({"checkstyle:JavadocMethod", "checkstyle:MultipleStringLiterals"})
public class RestExceptionHandler {
@Autowired
private ExceptionHandlerRegistry handlerRegistry;
@ExceptionHandler
public ResponseEntity handleThrowable(Throwable throwable, WebRequest request) {
request.setAttribute(Constants.ERROR_ATTRIBUTE_NAME, throwable, RequestAttributes.SCOPE_REQUEST);
Throwable ex = throwable instanceof CompletionException ?
ObjectUtils.defaultIfNull(throwable.getCause(), throwable) : throwable;
for (ApiExceptionHandler handler : handlerRegistry.getHandlers()) {
if (handler.isSupported(ex)) {
return handler.process(ex);
}
}
return new ResponseEntity<>(ApiResponse.badRequest(throwable, ApiResponseCode.SERVER_ERROR), HttpStatus.OK);
}
}
3)和ExceptionHandlerRegistry
:
@Component
public class ExceptionHandlerRegistry {
@Getter
private final List<ApiExceptionHandler> handlers;
@Autowired
public ExceptionHandlerRegistry(List<ApiExceptionHandler> handlers) {
this.handlers = ObjectUtils.defaultIfNull(handlers, Collections.emptyList());
}
}
错误消息:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is ru.filit.mvideo.mb2c.api.exceptions.RequestValidationException
更新 因此,在与@MichaelMichailidis进行了一些讨论之后,我尝试执行此操作,我只添加了一个内部@Configuration类以及所需的bean:
@TestConfiguration
static class SearchControllerTestConfiguration {
@Bean
public RequestValidationExceptionHandler requestValidationExceptionHandler(){
return new RequestValidationExceptionHandler();
}
@Bean
public ExceptionHandlerRegistry getExceptionHandlerRegistry(final RequestValidationExceptionHandler requestValidationExceptionHandler){
return new ExceptionHandlerRegistry(Collections.singletonList(requestValidationExceptionHandler));
}
@Bean
public RestExceptionHandler getRestExceptionHandler(){
return new RestExceptionHandler();
}
}
和我的测试合格。但是我不明白为什么在添加@ControllerAdvice之前没有配置就可以进行测试?
答案 0 :(得分:0)
您可以尝试在测试类中导入异常处理程序:
@RunWith(SpringRunner.class)
@Import(RestExceptionHandler.class) // EXCEPTION HANDLER CLASS
public class SearchControllerTest {