Как кодировать JSON в качестве параметра запроса с помощью Spring MockMVC

Я пытался в течение нескольких часов закодировать JSON в качестве параметра запроса для теста, который я пишу с использованием Spring MockMVC, но безуспешно.

Мой тест выглядит так

@Before
public void setUp() {       
    mockMvc = MockMvcBuilders.standaloneSetup(new TestController())
            .build();
}

@Test
public void shouldReturnJSONGeneratedByView() throws Exception {
    String sampleJson = "{\"key\":\"value\"}";

    String json = UriComponentsBuilder.newInstance()
    .path(sampleJson)
    .build().encode().toUriString();

    mockMvc.perform(MockMvcRequestBuilders.get("/Node?json="+json))
    .andExpect(status().isOk());
}

Но строка, которая достигает моего контроллера, по-прежнему закодирована ("%7B%22key%22:%22value%22%7D") и поэтому не может быть десериализована как JSON.

Чего мне не хватает, чтобы Spring понял закодированные параметры?

Спасибо за любую помощь


person Graham S    schedule 23.09.2015    source источник
comment
Почему вы просто декодируете его, а затем используете как JSON.   -  person erhun    schedule 23.09.2015
comment
Это часть существующего приложения, которое отлично работает при тестировании вручную (контроллер получает декодированный JSON), но я пытаюсь добавить некоторые автоматические тесты. Поскольку функциональность работает, я не хочу менять контроллер, если я что-то сломаю.   -  person Graham S    schedule 23.09.2015
comment
Хорошо, я понимаю, я не думаю, что вы что-то ломаете, проблема должна заключаться в том, что ваш конвертер JSON не работает, когда вы вызываете его из MockMvcRequestBuilders.get, потому что это не запрос на приход к Spring DispatcherServlet и некоторые аннотации (которые могут обеспечивать преобразования), возможно, это будет хорошо поделиться кодом контроллера и проверить конфигурацию тестов Spring. Честно говоря, контроллер не должен быть таким тестом, вы должны написать тесты для своего сервисного слоя.   -  person erhun    schedule 23.09.2015


Ответы (1)


Я считаю, что ваш JSON кодируется дважды, и поэтому контроллер получает строку, которая все еще закодирована (после того, как была декодирована только один раз).

Файл JavaDoc для MockMvcRequestBuilders сообщает следующее о первом параметре для get:

urlTemplate - шаблон URL; результирующий URL будет закодирован

Поэтому я думаю, что вам не нужно самостоятельно кодировать JSON, и должно работать следующее:

mockMvc.perform(MockMvcRequestBuilders.get("/Node?json={json}", sampleJson))
.andExpect(status().isOk());
person andersschuller    schedule 23.09.2015
comment
Спасибо! Это почти правильно, но я на правильном пути. Исправление заключалось в использовании urlTemplate mockMvc.perform(MockMvcRequestBuilders.get(/Node?json={json}, sampleJson)), в противном случае spring пытается расширить json, как если бы это был шаблон uri. Если вы обновите свой ответ, я буду рад принять его. - person Graham S; 24.09.2015
comment
имеет значение {json}, или вы могли бы поставить ?json={foo}? - person Snekse; 21.07.2017