2015-04-20 7 views
2

У меня установлена ​​Весенняя обувь приложение с использованием Gradle. Теперь я понимаю, что @EnableAutoConnfiguration настраивает приложение на основе зависимостей в пути к классу. Я очень рад избежать всякой сантехники, но все начинает происходить, чего я бы не хотел.Тестирование модулей с помощью MockServletContext

Вот моя зависимость:

dependencies { 
     compile('org.springframework.boot:spring-boot-starter-web:1.2.3.RELEASE') 
     compile 'org.springframework.hateoas:spring-hateoas:0.17.0.RELEASE' 
     compile 'org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE' 
     compile 'org.springframework.boot:spring-boot-starter-data-jpa' 

     compile 'com.google.guava:guava:18.0' 
     compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' 
     compile 'commons-beanutils:commons-beanutils:1.9.2' 
     runtime 'org.hsqldb:hsqldb:2.3.2' 

     testCompile 'org.springframework.boot:spring-boot-starter-test' 
     testCompile 'com.jayway.jsonpath:json-path:2.0.0' 
    } 

Моего класс приложение:

@ComponentScan("org.home.project") 
@SpringBootApplication 
//@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL) 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

Отрывок из UserController:

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) 
public HttpEntity<ResourceSupport> create(@Valid @RequestBody UserCreateRequest ucr, BindingResult bindingResult) { 
    if (bindingResult.hasErrors()) throw new InvalidRequestException("Bad Request", bindingResult); 

    Long userId = userService.create(ucr); 

    ResourceSupport resource = new ResourceSupport(); 
    resource.add(linkTo(UserEndpoint.class).withSelfRel()); 
    resource.add(linkTo(methodOn(UserEndpoint.class).update(userId, null, null)).withRel(VIEW_USER)); 
    resource.add(linkTo(methodOn(UserEndpoint.class).delete(userId)).withRel(DELETE_USER)); 

    return new ResponseEntity(resource, HttpStatus.CREATED); 
} 

UserController.java имеет два аннотаций:

@RestController 
@RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE) 

Прежде всего - обратите внимание на примечание @EnableHyperdiaSupport - ссылки в экземпляре ResourceSupport по-прежнему сериализуются в формате hal + json, несмотря на тип медиафайла и тип носителя, заданный в запросе. Это происходит автоматически, когда 'org.springframework.plugin: spring-plugin-core: 1.2.0.RELEASE' введен в зависимостях. Как можно настроить его явно?

Другая проблема - это единичные тесты.

Это проходит:

@RunWith(SpringJUnit4ClassRunner.class) 
    @SpringApplicationConfiguration(classes = MockServletContext.class) 
    @WebAppConfiguration 
    public class UserControllerTest { 
    ...ommited for brevity... 

@InjectMocks 
    private UserController testObject; 

    @Before 
    public void setUp() throws Exception { 
     initMocks(this); 
     mockMvc = standaloneSetup(testObject).build(); 
    } 

    @Test 
     public void testUserCreatedLinks() throws Exception { 
      mockMvc.perform(post("/users").contentType(MediaType.APPLICATION_JSON).content(data)) 
      .andExpect(status().isCreated()) 
      .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andExpect(jsonPath("$.links.[*].rel", hasItem("self"))); 
     } 
    ...ommited fro brevity... 
    } 

сообщение Запрос возвращает стандартный ответ JSON в тесте - не HAL + JSON. Есть ли способ переконфигурировать это, чтобы модульное тестирование @RestController с MockServletContext создавало HAL + JSON или возвращалось к проблеме номер 1 - как настроить формат ответа явно, чтобы сериализатор Jackson не производил hal + json?

+1

вы видели 'org.springframework.hateoas.MediaTypes.HAL_JSON'? –

+0

Хм, но @JoaoEvangelista, то почему запрос во время выполнения для контроллера с явно определенным Media-Type: «application/json» возвращает ответ с типом медиафайла «application/json», но по-прежнему является «приложением/hal + json» ? если я удаляю, выдает значение из конфигурации сопоставления, тогда ответ имеет Media-Type: «application/hal-json». – Xeperis

ответ

6

Выполнение теста выполняется с использованием теста Spring MVC Test standaloneSetup, который использует минимальную конфигурацию для запуска вашего контроллера. Эта конфигурация не совпадает с конфигурацией, которая будет использоваться при запуске всего приложения.

Если вы хотите использовать ту же конфигурацию, можно использовать webAppContextSetup:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class) 
@WebAppConfiguration 
public class SomeTests { 

    @Autowired 
    private WebApplicationContext context; 

    private MockMvc mockMvc; 

    @Before 
    public void setUp() { 
     this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); 
    } 
} 

В качестве альтернативы, вы можете повторить конфигурацию Spring HATEOAS в отдельной установке. Обратите внимание, что это приводит к тому, что конфигурация ваших тестов отличается от конфигурации вашего приложения. Вы бы создать экземпляр MockMvc вроде этого:

TypeConstrainedMappingJackson2HttpMessageConverter messageConverter = 
      new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class); 
messageConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON)); 

ObjectMapper objectMapper = messageConverter.getObjectMapper(); 
objectMapper.registerModule(new Jackson2HalModule()); 
objectMapper.setHandlerInstantiator(
     new Jackson2HalModule.HalHandlerInstantiator(new DefaultRelProvider(), null)); 

MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testObject) 
     .setMessageConverters(messageConverter).build(); 
+0

Но есть ли способ добавить некоторую конфигурацию к минимальному минимуму без переключения контекстов? – Xeperis

+1

Возможно, хотя я не уверен, что рекомендую его. См. Мое редактирование. –

+0

В конце этого, я знаю, но это может помочь кому-то еще в будущем: мне также не понравилась идея репликации конфигурации HATEOAS вручную. Я нашел это решение, которое позволило мне напрямую использовать конфигурацию HATEOAS: https://stackoverflow.com/a/20364181/488932 –

Смежные вопросы