2016-12-02 5 views
3

После создания ресурса в Spring REST Controller я возвращаю его местоположение в заголовке, как показано ниже.Unit Testing Заголовок «Location» контроллера Spring REST

@RequestMapping(..., method = RequestMethod.POST) 
public ResponseEntity<Void> createResource(..., UriComponentsBuilder ucb) { 

    ... 

    URI locationUri = ucb.path("/the/resources/") 
     .path(someId) 
     .build() 
     .toUri(); 

    return ResponseEntity.created(locationUri).build(); 
} 

В модульном тесте я проверяю его местоположение, как показано ниже.

@Test 
public void testCreateResource(...) { 
    ... 
    MockHttpServletRequestBuilder request = post("...") 
     .content(...) 
     .contentType(MediaType.APPLICATION_JSON) 
     .accept(MediaType.APPLICATION_JSON); 

    request.session(sessionMocked); 

    mvc.perform(request) 
     .andExpect(status().isCreated()) 
     .andExpect(header().string("Location", "/the/resources" + id); 
} 

Этот результат не подходит для следующего сообщения.

java.lang.AssertionError: Response header Location expected:</the/resources/123456> but was:<http://localhost/the/resources/123456> 

Похоже, я должен предоставить контекстную префикс http://localhost для размещения заголовка в ожидании.

  • Безопасно ли в контексте жесткого кода? Если да, то почему?
  • Если нет, то каков правильный способ его правильной генерации для тестового примера?

ответ

1

Если вам не нужно иметь полный URI в заголовке местоположения в ответе (т. Е. Нет требований, ограничений проектирования и т. Д.): Рассмотрите возможность переключения на относительный URI (который действителен с точки зрения стандартов HTTP - см. [1]: https://tools.ietf.org/html/rfc7231) Относительные URI - предлагаемый стандарт, поддерживаемый современными браузерами и библиотеками. Это позволит вам проверить поведение конечной точки и сделать ее менее хрупкой в ​​долгосрочной перспективе.

Если вам необходимо утвердить полный путь, так как вы используете MockMvc, вы можете установить Ури в запросе на тест именно то, что вы хотите:

@Autowired 
private WebApplicationContext webApplicationContext; 

@Test 
public void testCreateResource() { 
    MockMvc mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 
    mvc.perform(MockMvcRequestBuilders.get(new URI("http://testserver/the/resources"))); 

Это сделает впрыскивается строитель продукции "http://testserver «когда вызывается сборка. Обратите внимание, что изменение каркаса в будущем может привести к головным болям, если они удалили это тестовое поведение.

2

Я угадываю, потому что вы используете UriComponentsBuilder для создания своего URI, это настройка имени хоста в вашем заголовке местоположения. Если бы вы использовали что-то вроде new URI("/the/resources"), ваш тест прошел бы.

В вашем случае, я хотел бы использовать redirectedUrlPattern, чтобы соответствовать Перенаправление URL:

.andExpect(redirectedUrlPattern("http://*/the/resources"))

Это будет соответствовать любому хосту, так что вам не придется жёстко Localhost. Узнайте больше о различных шаблонах, которые можно использовать с AntPathMatcherhere.

+0

Ваше решение проверяет поведение перенаправления. OP хотел, чтобы был проверен заголовок местоположения. Должен признаться, я не знал о 'redirectedUrlPattern' до сегодняшнего дня –