我想在模拟单元测试中获得json对异常的响应。 这是我的应用程序配置文件。
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.spring")
public class AppConfig extends WebMvcConfigurerAdapter{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
这是我现有用户的异常类:
public class ConflictException extends RuntimeException{
public ConflictException() {
}
public ConflictException(String message) {
super(message);
}
}
这是我用@ControllerAdvice注释的全局异常控制器类。
@EnableWebMvc
@ControllerAdvice
public class GlobalExceptionHandlerController extends ResponseEntityExceptionHandler{
public GlobalExceptionHandlerController() {
super();
}
@ExceptionHandler(ConflictException.class)
public ResponseEntity<Map<String, Object>> handleException(
Exception exception, HttpServletRequest request) {
ExceptionAttributes exceptionAttributes = new DefaultExceptionAttributes();
Map<String, Object> responseBody = exceptionAttributes.getExceptionAttributes(exception, request, HttpStatus.CONFLICT);
return new ResponseEntity<Map<String,Object>>(responseBody, HttpStatus.CONFLICT);
}
}
现在,这是我的控制器测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@EnableWebMvc
@ActiveProfiles("Test")
@ContextConfiguration(classes={AppConfig.class})
public class UserControllerTest {
@InjectMocks
private UserController userController;
@Mock
private UserService service;
private MockMvc mockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
final ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
//here we need to setup a dummy application context that only registers the GlobalControllerExceptionHandler
final StaticApplicationContext applicationContext = new StaticApplicationContext();
applicationContext.registerBeanDefinition("advice", new RootBeanDefinition(GlobalExceptionHandlerController.class, null, null));
//set the application context of the resolver to the dummy application context we just created
exceptionHandlerExceptionResolver.setApplicationContext(applicationContext);
//needed in order to force the exception resolver to update it's internal caches
exceptionHandlerExceptionResolver.afterPropertiesSet();
mockMvc = MockMvcBuilders.standaloneSetup(userController).setHandlerExceptionResolvers(exceptionHandlerExceptionResolver).build();
}
@Test
public void createUserExistsTest() throws Exception {
when(service.createUser(any(User.class))).thenThrow(new ConflictException("User exists."));
mockMvc.perform(post("/user")
.content("{\"username\": \"bimal\", \"password\": \"check\", \"email\": \"test@gmail.com\", \"maxCaloriesPerDay\": \"1000\"}")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isConflict());
}
}
当我运行我的测试方法时,出现以下错误:
错误:
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> com.spring.app.exception.GlobalExceptionHandlerController.handleException(java.lang.Exception,javax.servlet.http.HttpServletRequest)
java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.LinkedHashMap
at org.springframework.util.Assert.isTrue(Assert.java:68)
如何解决此错误?抛出异常但我无法转换并使用它。
答案 0 :(得分:1)
我在这一年上已经太晚了一年,但为了将来的参考,这解决了我的问题。
问题是您的异常解析器不知道任何消息转换器,因为您为它提供了静态应用程序上下文。
可以通过以下代码直接解决,直接在exceptionHandlerExceptionResolver.setApplicationContext(applicationContext)
:
exceptionHandlerExceptionResolver.setMessageConverters(
Collections.singletonList(new MappingJackson2HttpMessageConverter(new ObjectMapper()))
);
答案 1 :(得分:0)
正在处理中。此错误指的是响应实体类型没有HttpMessageConverter。将JacksonHttpMessageConverter添加到spring上下文中。
在AppConfig中从WebMvcConfigurerAdapter覆盖此方法:
@Override
public void configureMessageConverters(List<HttpMessageConverter> converters) {
messageConverters.add(new MappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}