Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用@ControllerAdvice测试@RestController_Java_Spring_Junit - Fatal编程技术网

Java 使用@ControllerAdvice测试@RestController

Java 使用@ControllerAdvice测试@RestController,java,spring,junit,Java,Spring,Junit,我的问题与测试Spring@RestController有关,它也在使用@ControllerAdvice和@ExceptionHandler。代码如下: @控制器建议等级: @ControllerAdvice public class MyAppExceptionHandler { @ExceptionHandler({ NoSuchEntityException.class }) @ResponseStatus(value = HttpStatus.NOT_FOUND)

我的问题与测试Spring@RestController有关,它也在使用@ControllerAdvice和@ExceptionHandler。代码如下:

@控制器建议等级:

@ControllerAdvice
public class MyAppExceptionHandler {

    @ExceptionHandler({ NoSuchEntityException.class })
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public @ResponseBody
    ErrorDTO handleNotFoundException(Exception ex) throws IOException {

        return new ErrorDTO.Builder().setStatus(HttpStatus.NOT_FOUND)
                .setCause(ex.getClass().getName())
                .setThrowable(ex).build();
    }
}
当在应用程序中使用它时,一切都很好——用JSON解释完美地得到404响应,但当在测试中尝试使用它时——坏事情发生了

我的测试班:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { WebConfig.class })
@WebAppConfiguration
public class SomeTest {

    @Mock
    private SomeService service;

    @InjectMocks
    private SomeController controller;

    private MockMvc mvc;

    private ExceptionHandlerExceptionResolver createExceptionResolver() {
        ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
            @Override
            protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
                HandlerMethod handlerMethod, Exception exception) {
                Method method = new ExceptionHandlerMethodResolver(
                        MyAppExceptionHandler.class).resolveMethod(exception);
                return new ServletInvocableHandlerMethod(
                    new MyAppExceptionHandler(), method);
            }
        };
        exceptionResolver.afterPropertiesSet();
        return exceptionResolver;
    }

    @Before
    public void setup() {

        MockitoAnnotations.initMocks(this);
        mvc = MockMvcBuilders.standaloneSetup(controller)
                .setHandlerExceptionResolvers(createExceptionResolver())
                .build();
    }

    @Test
    public void thatExceptionHappens() throws Exception {

        when(service.get(10)).thenThrow(new NoSuchEntityException(Some.class, 10));

        mvc.perform(get("/api/some/10")).andExpect(status().isNotFound());
    }
}
尝试运行时:

2014-07-15 19:35:01.376 [main] ERROR com.package.SomeTest$1 - Failed to invoke @ExceptionHandler method: public com.package.ErrorDTO com.package.MyAppExceptionHandler.handleNotFoundException(java.lang.Exception) throws java.io.IOException
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
我认为在测试mine@ExceptionHandler的过程中可能没有加载MappingJackson2HttpMessageConverter(不过它是在WebConfig.class中配置的,并且在尝试执行典型测试时—没有引发任何异常—一切正常)


提前感谢您的帮助。

我不确定这是否是解决此问题的最佳解决方案(我想听听其他解决方案),
但这正是我解决您所面临的问题的方法:

将此行添加到您的
createExceptionResolver()

大概是这样的:

private ExceptionHandlerExceptionResolver createExceptionResolver(){
ExceptionHandlerExceptionResolver exceptionResolver=新的ExceptionHandlerExceptionResolver(){
@凌驾
受保护的ServletInvocableHandlerMethod getExceptionHandlerMethod(
HandlerMethod HandlerMethod,异常(异常){
方法方法=新异常HandlerMethodResolver(
MyAppExceptionHandler.class).resolveMethod(异常);
返回新的ServletInvocableHandlerMethod(
新的MyAppExceptionHandler(),方法);
}
};
exceptionResolver.getMessageConverters().add(新映射Jackson2HttpMessageConverter());
exceptionResolver.afterPropertiesSet()异常;
返回异常解析器;
}
出于某种我不知道的原因,Spring没有加载我的MappingJackson2HttpMessageConverter。

这句话解决了我的问题。

MockMvcBuilders standaloneSetup根据定义是手动的,这意味着它不需要在Spring配置中发现像@ControllerAdvice这样感兴趣的Spring bean,而是允许您手动设置测试所需的内容。相反,standaloneSetup应该允许您手动注册@ControllerAdvice bean。要做到这一点是有条件的。请参阅。

您的网络配置的内容是什么?您提出了一个问题,人们已经花时间回答了。请接受答案。请注意,当您在构建器中设置
HandlerExceptionResolver
时,您将删除所有默认值,并使用您的值代替它们。如果您有任何使用验证注释的测试,并且期望从Spring得到适当的响应,那么这可能会导致问题。我在Spring上提出了一个问题,要求他们允许我们添加解析程序,而不是覆盖:今天我花了3个小时,直到我像您一样使用exceptionResolver.getMessageConverters().add(…)解决了这个问题。真恶心!默认情况下,ExceptionHandlerExceptionResolver构造函数中只添加了4个转换器,Jackson不在其中。感谢@Rossen实现了这一点。Spring 4.2附带了这一改进,Spring Boot 1.3.0也有这一改进,因为它依赖于Spring 4.2+。
exceptionResolver.getMessageConverters().add(
        new MappingJackson2HttpMessageConverter());