Тестирование сопоставления JSON для клиента Spring Boot RestTemplate - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть REST API вне моего контроля (предоставленный другой, удаленной командой), который мне нужно использовать из приложения Spring Boot.

В настоящее время я хотел бы написать тест для того, чтобы запрос (не ответ), полученный в результате моего вызова RestTemplate, точно соответствовал тому, что ожидается на удаленном конце.У меня есть образец JSON-фрагмента, который я хотел бы скопировать из своего кода - учитывая те же параметры, что и в примере, я должен получить эквивалентный JSON-фрагмент в теле запроса, который я хотел бы проанализировать, чтобы быть уверенным.

Моя идея пока заключается в том, чтобы заставить RestTemplate использовать сервер под моим контролем, который затем захватывает запрос JSON.Очевидно, MockRestServiceServer - хороший выбор для этого.

Это правильный подход?Как настроить MockRestServiceServer, чтобы позволить мне это сделать?

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Согласно документации, вы можете сопоставлять запросы, используя пути json в Mock.Например;

RestTemplate restTemplate = new RestTemplate()
 MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();

server.expect(ExpectedCount.once(), requestTo(path))
                .andExpect(method(HttpMethod.POST))
                .andExpect(jsonPath("$", hasSize(1)))
                .andExpect(jsonPath("$[0].someField").value("some value"))

Примечание: я не проверял это.

Но я добился того, что вы ищете, используя Wire Mock много раз.Это снова намного лучший вариант, чем MockRestServiceServer.Почему я так говорю?

  • широкое внедрение и поддержка
  • более элегантный и обширный запрос и ответ, сопоставление
  • высокая конфигурация
  • запись и воспроизведение
  • конфигурируемая защита / аутентификация
  • вы можете даже докеризовать это

Взгляните на http://wiremock.org/docs/request-matching/

0 голосов
/ 12 февраля 2019

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

В качестве альтернативы вы можете добавить запросите регистратор на ваш RestTemplate, который регистрирует каждый запрос.Это упростит проверку правильности отправленного запроса в любое время, если возникнут проблемы.

0 голосов
/ 12 февраля 2019

Если вы заинтересованы только в проверке сопоставления JSON, вы всегда можете напрямую использовать ObjectMapper Джексона и проверить, совпадают ли структуры объектов, используя библиотеку, такую ​​как JSONassert , чтобы проверить, соответствует ли сериализованная строкаваш ожидаемый результат.Например:

@Autowired
private ObjectMapper objectMapper;
private Resource expectedResult = new ClassPathResource("expected.json");

@Test
public void jsonMatches() {
    Foo requestBody = new Foo();
    String json = objectMapper.writeValueAsString(requestBody);
    String expectedJson = Files
        .lines(expectedResult.getFile())
        .collect(Collectors.joining());
    JSONAssert.assertEquals(expectedJson, json, JSONCompareMode.LENIENT);
}

В этом тесте чисто используется ObjectMapper для проверки сопоставления JSON и ничего больше, поэтому вы можете даже сделать это без необходимости начальной загрузки Spring в вашем тесте (что может быть быстрее),Недостатком этого является то, что если вы используете другую среду, чем Джексон, или если RestTemplate меняет свою реализацию, этот тест может устареть.


В качестве альтернативы, если вы заинтересованы впроверяя, что полный запрос соответствует (как URL, метод запроса, тело запроса и т. д.), вы можете использовать MockRestServiceServer, как вы упомянули.Это можно сделать, добавив аннотацию @SpringBootTest к своему тесту, автоматическое подключение RestTemplate и службу, которая вызывает RestTemplate, например:

@RunWith(SpringRunner.class)
@SpringBootTest
public class FooServiceTests {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private FooService fooService; // Your service

    private MockRestServiceServer server;

    @Before
    public void setUp() {
        server = MockRestServiceServer.bindTo(restTemplate).build();
    }
}

Затем вы можете настроить свои тесты, используя:

@Test
public void postUsesRestTemplate() throws IOException, URISyntaxException {
    Path resource = Paths.get(getClass().getClassLoader().getResource("expected-foo.json").toURI());
    String expectedJson = Files.lines(resource).collect(Collectors.joining());
    server.expect(once(), requestTo("http://example.org/api/foo"))
        .andExpect(method(HttpMethod.POST))
        .andExpect(MockRestRequestMatchers.content().json(expectedJson))
        .andRespond(withSuccess());
    // Invoke your service here
    fooService.post();
    server.verify();
}
...