В одном предложении: Я хочу, чтобы MockMvc
работал так, как если бы я напрямую вызывал контроллер .
(PS Это синтаксический сахар Это не означает Я действительно вызываю контроллеры, когда интеграционный тест .)
Подробности:
Скажем, у нас есть контроллер Restful:
class BookController {
public Book updateBook(int id, Book newBook) {...}
}
Типичное пружинное интеграционное тестирование для службы RESTful выглядит следующим образом:
mockMvc.perform(put("/books/1")
.content("{\"id\":1, \"name\": \"ABC\", ...}")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON))
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is(1)))
.andExpect(jsonPath("$.name", is("ABC")))
...and more...;
Однако можем ли мы делать такие вещи, как:
BookController magicBookController = SomeMagic.generate_the_magic_controller();
Book result = magicMvc.perform(magicBookController.updateBook(1, new Book("ABC", ...)));
assertThat(1, result.getId());
assertThat("ABC", result.getName());
...
РЕДАКТИРОВАТЬ : код выше , а не , просто вызывая метод new BookController().updateBook(...)
! Я надеюсь, что generate_the_magic_controller
будет генерировать динамические прокси c (используя cglib). Затем, когда мы вызываем magicBookController.updateBook
, фактически динамически сгенерированный код выглядит следующим образом:
Book dynamically_generated_updateBook(int id, Book book) {
String url = magic_assemble_url(id); // will become: "/books/1"
String content = magic_assemble_content(book); // will become: "{name: AAA, ...}"
Something result = mockMvc.perform(put(url)
.content(content)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON));
return parse_result(result); //parse back into book
}
В одном предложении: Я хочу, чтобы MockMvc
работал так, как если бы я был прямой вызов контроллера . Мой вопрос:
- Должен ли я это сделать? (Или это очень плохая практика?)
- Как это сделать? Я собираюсь взломать часть в среде Spring о «поиске и разборе контроллеров», но у меня нет конкретных идей о том, как это сделать ...
РЕДАКТИРОВАТЬ : My Цель тестирования заключается в следующем. Изначально людям нравилось тестировать код своими глазами (давать входные данные, смотреть на результаты и утверждать их умом). Конечно, это плохо. Поэтому мы записываем такие вещи, как «опубликовать в / books и заявить, что результаты верны». Это то, что я хочу проверить. Это на самом деле немного похоже на тест E2E (так как это спокойный сервис) ИМХО. (Или моя цель полностью неверна?)
РЕДАКТИРОВАТЬ : Типичный тест в Джерси, который, как мне кажется (лично), более элегантен, чем тесты в Спринге:
Profile profile = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertEquals(profile.getXXX(), "aaa");
...
Большое спасибо за любые идеи!