Завершено 406 NOT_ACCEPTABLE - Тестирование WebLayer в SpringBoot

Dec 07 2020

У меня есть этот метод в приложении Spring Boot v2.1.0.RELEASE.

@GetMapping(value = "/wildProject", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<WildProject>> getList(HttpServletRequest request,
        HttpServletResponse response)
        throws Exception {

    List<WildProject> list = authorisationService.getList();

    System.out.println("-----------------");
    System.out.println(list);
    System.out.println("-----------------");

    return ok().body(list);


} 

и этот тест:

 this.mockMvc.perform(get("/wildProject")
  //.accept(MediaType.APPLICATION_JSON_UTF8_VALUE))
  // .andDo(print())
  .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  .andExpect(status().isOk());

и вот результат теста:

20:03:38.253 [main] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Using 'application/json', given [*/*] and supported [application/json]
20:03:38.255 [main] WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
20:03:38.256 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Completed 406 NOT_ACCEPTABLE

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /wildProject
       Parameters = {}
          Headers = {Content-Type=[application/json;charset=UTF-8]}
             Body = null
    Session Attrs = {}

Handler:
             Type = com.bonansa.controller.AuthorisationController
           Method = public org.springframework.http.ResponseEntity<java.util.List<com.bonansa.WildProject>> com.bonansa.controller.AuthorisationController.getList() throws java.lang.Exception

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.web.HttpMediaTypeNotAcceptableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 406
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

и

@JsonSerialize(as = IWildProject.class)
public interface IWildProject {
..
}

Ответы

s7vr Dec 19 2020 at 04:59

Ваша проблема возникает двояко.

Основная проблема: вы не зарегистрировали нужный конвертер сообщений, чтобы иметь возможность писать ответ json. Это скрыто из-за ошибки, из-за которой сервер должен возвращать 500 вместо 406 из-за неправильной конфигурации, поскольку контроллер указал аннотацию создания, а у клиента есть заголовок accept для всех.

Подробнее - https://github.com/spring-projects/spring-framework/issues/23287

Это больше не проблема в последней версии, проблема только с весенней загрузочной версией 2.1.x.

2 x80486 Dec 08 2020 at 00:48

Вам не нужно устанавливать Content-Typeзаголовок для GETзапросов, поскольку вы ничего не отправляете, а что-то просите. AcceptЗаголовок это то , что ищут в этом случае.

Более того, MediaType.APPLICATION_JSON_VALUEне совпадет MediaType.APPLICATION_JSON_UTF8_VALUE.

Я бы рекомендовал реорганизовать этот фрагмент кода в:

this.mockMvc.perform(get("/wildProject")
  .accept(MediaType.APPLICATION_JSON_VALUE))
  // .andDo(print())
  .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  .andExpect(status().isOk());