2016-04-11 6 views
1

Я собираюсь круглыми кругами, пытаясь исправить тест, и ничто в SO или других онлайн-источниках не предоставило решение. У меня есть этот @ControllerAdvice метод для обработки MyException Exception, который:@ExceptionHandler не был вызван тест

@ControllerAdvice 
public class MyControllerAdvice { 
    @ExceptionHandler(MyException.class) 
    @ResponseBody 
    public HttpEntity<ErrorDetail> handleMyException(MyException exception) { 
     return new ResponseEntity<>(exception.getErrorDetail(), exception.getHttpStatus(); 
    } 
} 

И у меня есть контроллер:

@Controller 
@RequestMapping(value = "/image") 
public class ImageController { 
    @Autowired 
    private MyImageService imageService; 

    @RequestMapping(value = "/{IMG_ID}", method = RequestMethod.GET, 
     produces = MediaType.IMAGE_PNG_VALUE) 
    public HttpEntity<?> getImage(String imageId) { 
     byte[] imageBytes = imageService.findOne(imageId); // Exception thrown here 
     .... 
     return new ResponseEntity<>(imageBytes, HttpStatus.OK); 
    } 
    ... 
} 

которая протестирована:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = MyApplication.class) 
@WebAppConfiguration 
@IntegrationTest("server.port:0") 
public class ThumbnailControllerTest { 
    @Autowired 
    private ImageController testObject; 
    private ImageService mockImageService = mock(ImageService.class); 

    @Autowired 
    protected WebApplicationContext webApplicationContext; 
    private MockMvc mockMvc; 

    @Before 
    public void setup() { 
     testObject.setImageService(mockImageService); 
     mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
    } 

    @Test 
    public void testImageWhichDoesntExistReturns404() { 
      doThrow(new MyException("Doesn't exist", HttpStatus.NOT_FOUND)) 
       .when(mockImageService).findOne(anyString()); 

      mockMvc.perform(get("/image/doesnt_exist")) 
       .andExpect(status().isNotFound()); 
    } 
} 

У меня есть аналогичные установки для других тестов, но они, похоже, проходят. Однако для этого я получаю: Failed to invoke @ExceptionHandler method: public org.springframework.http.HttpEntity<mypackage.ErrorDetail>, однако я знаю, что он вызывается, потому что, когда я выхожу через него, вызывается, и журналы показывают, что он был обнаружен (Detected @ExceptionHandler methods in MyControllerAdvice).

Мои мысли в том, что это связано с тем, что HttpMessageConverters не устранены правильно и попытаются разрешить вывод с использованием подхода ModelAndView, а не требуемого формата JSON. Я не смог заставить это сделать, используя standaloneSetup для MockMvc (настроенный с помощью набора ControllerAdvice и HttpMessageConverters) или принудительно используя его с помощью компонента HttpMessageConverters требуемого типа.

Я использую пружинные зависимости:

org.springframework.boot:spring-boot-starter-web:jar:1.3.1.RELEASE 
org.springframework.boot:spring-boot-starter:jar:1.3.1.RELEASE 
org.springframework.boot:spring-boot-starter-test:jar:1.3.1.RELEASE 
org.springframework.boot:spring-boot-starter-data-rest:jar:1.3.1.RELEASE 

Что я делаю неправильно?

ответ

1

Я смог отслеживать это до produces = MediaType.IMAGE_PNG_VALUE. Если вы удалите это, он отлично работает (если ваш ErrorDetail является JSON-сериализуемым). Дело в том, что AbstractMessageConverterMethodProcessor палочки с запрошенным типом. Он просто пропускает конвертер JSON, потому что он не может создавать изображение/png. Указание produces = {MediaType.IMAGE_PNG_VALUE, MediaType.APPLICATION_JSON_VALUE} не помогает: он просто выбирает первый тип и придерживается его.

Мне не удалось выяснить, как заставить его работать с produces. Любые улучшения или исправления приветствуются.

+0

Спасибо, что очень помог, я указал тип содержимого как заголовок ответа, который отлично работает в отличие от 'производит', который разрешил проблему. – joelc