Как имитировать ответ внешнего API, вызываемого из внутреннего теста интеграции API - PullRequest
1 голос
/ 08 мая 2020

Я пишу интеграционные тесты для приложения, которое использует внутренний REST API для выполнения действия; все Java.
В API есть метод POST, который вызывает внешний API. В тесте мне нужно отправить запрос к моему API для выполнения действия.
Проблема в том, что я не хочу отправлять реальные запросы к внешнему API при запуске интеграционных тестов.
Как я могу имитировать ответ на внешний вызов API?
Есть ли способ, которым я все еще могу отправить запрос POST в свой API (имитируемый или другой) в моем тесте, но использовать фиктивный ответ для внешнего вызова, выполненного в методе Java POST?

1 Ответ

0 голосов
/ 08 мая 2020

Я сделал это следующим образом: создал уровень сервиса, который делает вызовы API внешним сервисам. Я построил свой на Spring RestTemplate, но вы можете использовать любую библиотеку для вызовов. Так что у него будут такие методы, как get () или post ().

Затем я использую Postman для выполнения некоторых запросов к внешнему API, сохраняю ответы в файлах и добавляю эти файлы в свой проект.

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

I используйте EasyMock, но подойдет любая имитирующая библиотека. Вот пример того, как выглядит тест.

    @Test
    public void test_addPhoneToExternalService() {
        // Mock my real API service.
        ApiService mockApiService = EasyMock.createMock(ApiService.class);
        // Construct my service under test using my mock instead of the real one.
        ServiceUnderTest serviceUnderTest = new ServiceUnderTest(mockApiService);
        // Expect the body of the POST request to look like this.
        Map<String, Object> requestBody = new HashMap<String, Object>() {{
            put("lists", 0);
            put("phone", "800-555-1212");
            put("firstName", "firstName");
            put("lastName", "lastName");
        }};
        // Read the response that I manually saved as json.
        JsonNode expectedResponse = Utils.readJson("response.json");
        expect(mockApiService.post(anyObject(),
                eq("https://rest.someservice.com/api/contacts"), eq(serialize(requestBody))))
                .andReturn(expectedResponse);
        EasyMock.replay(mockApiService);
        // Call the code under test. It ingests the response 
        // provided by the API service, which is now mocked, 
        // and performs some operations, then returns a value 
        // based on what the response contained (for example, 
        // "{\"id\":42}").
        long id = serviceUnderTest.addPhone("firstName", "lastName", "800-555-1212");
        Assert.assertThat(id, is(42L));
        EasyMock.verify(mockApiService);
    }

Надеюсь, что поможет!

...