Ложный вызов и ответ от стороннего API - PullRequest
2 голосов
/ 01 октября 2019

Я звоню сторонней конечной точке, так сказать. Я просто вызываю конечную точку и анализирую ответ.

public ListUsers listUsers() {
    String url = "/api/v1/account/?apikey=" + apiKey;
    String signature = null;
    try {
        signature = generateSignature(url);
    } catch (SignatureException e) {
        e.printStackTrace();
    }

    Call newCall = apiCall("GET", url, signature, null);

    Type localVarReturnType = new TypeToken<ListUsers>() { }.getType();
    ApiResponse<ListUsers> responseFromApiClient = apiClient.execute(newCall, localVarReturnType);
    return responseFromApiClient.getData();
}

listUsers () func был реорганизован для лучшей абстракции

public ListUsers listUsers() {
    String url = "/api/v1/account/?apikey=" + apiKey;
    Type localVarReturnType = new TypeToken<ListUsers>() { }.getType();
    ApiResponse<ListUsers> responseFromApiClient = apiClient.execute(buildApiCall("GET", url, null), localVarReturnType);
    return responseFromApiClient.getData();
}

Эта конкретная конечная точка не требуетв любом теле, и возвращает json, который я затем анализирую.

{
    "meta": {
        "limit": 0,
        "offset": 0,
        "total_count": 1
    },
    "objects": [
        {
            "address_one": "",
            "address_three": "",
            "address_two": "",
            "country_code": "",
            "cs_domain_id": null,
            "date_joined": "2019-07-05T13:50:21",
            "disable_personal_account": false,
            "email": "noreply@some.com",
            "first_name": "",
            "id": 1,
            "is_reseller": true,
            "is_superuser": true,
            "is_verified": true,
            "last_login": null,
            "last_name": "",
            "paywall": true,
            "postal_code": "",
            "projects": [],
            "reference_number": "",
            "reseller_id": 1,
            "reseller_name": "ROOT",
            "reseller_rights": [
                {
                    "domain_id": null,
                    "id": 1,
                    "level": "owner",
                    "name": "ROOT"
                }
            ],
            "resource_uri": "/api/v1/account/1/",
            "saml": false,
            "state": 0,
            "status": "enabled",
            "surname": "",
            "username": "admin",
            "uuid": "1c208540-3ed9-4741-a936-a574a3ded12a"
        }
    ]
}

И затем этот ответ json анализируется.

Как мне написать для этого подходящий модульный тест, или нетнужно? Единственный тест, который я придумал, - это просто базовый тест, в котором я на самом деле вызываю сервис, а что касается чистого модульного теста, который не будет работать на моем сервере сборки. Вот тест

@Test
void getListProjectsTest() {
    GqConsoleApiClient gcac = new GqConsoleApiClient();
    ListProjects response = gcac.listProjects();
    System.out.println(listProjects);
    Assert.assertEquals(20, response.getMeta().getLimit());
    Assert.assertEquals("some-customer-id", response.getObjects().get(0).getCustomerId());
}

Ответы [ 2 ]

2 голосов
/ 01 октября 2019

Есть несколько способов сделать это. На вашем месте я бы сделал это следующим образом:

  1. Сначала создайте файл json с правильным ответом

  2. Напишите контрольный пример, в котором

    2.1. Загрузите файл json в тестовый класс

    File sampleFile = new File(URLDecoder.decode(classLoader.getResource("jsonFilePath").getFile(), "UTF-8"));  
    

    2.2. Преобразуйте этот файл в тип Java, который будет возвращен из стороннего API. В вашем случае это ApiResponse<ListUsers>. Для этого вы можете использовать библиотеки Джексона или Gson

    2.3. Вы должны создать макет типа apiClient и смоделировать вызов execute. И вернуть объект Java, полученный из шага 2.2. Примерно так

    when(apiClient.execute(any(), any()).thenReturn(....)  
    

    2.4 записывает утверждения для проверки различных аспектов java-объектов

Таким образом, вы можете легко создавать несколько файлов json для проверки различных ответов отапи.

1 голос
/ 01 октября 2019

Как мне написать подходящий модульный тест для этого или он не нужен?

С точки зрения модульных тестов ваша логика довольно краткая.
Вы вызываете API:

ApiResponse<ListUsers> responseFromApiClient = apiClient.execute(newCall, localVarReturnType);

А в следующем утверждении:

return responseFromApiClient.getData();

вы просто возвращаете getData().

Итак, с точки зрения модульного тестирования, вам нужно смоделировать возвращение execute() с любым объектом ApiResponse<ListUsers> и утверждать, что вы возвращаете getData() из этого объекта.

Что-то в этом роде:

// GIVEN
ApiResponse<ListUsers> responseFromApiClientByMock = Mockito.any();
Data dataByMock = Mockito.when(responseFromApiClientByMock.getData()).thenReturn(Mockito.mock(Data.class);
Mockito.when(apiClientMock.execute(newCall, localVarReturnType)).thenReturn(responseFromApiClientByMock);
// WHEN
Data actualData = foo.listUsers();
// THEN
Assertions.assertSame(dataByMock, actualData);

Конечно, такой тип компонента для тестирования дает очень поверхностные модульные тесты.
Так что вы должны окончательно создать интеграционные тесты для метода listUsers()или, возможно, на методе более высокого уровня, потому что вы не хотите дублировать логику тестирования интеграции на каждом уровне.

Вы можете обратиться к ответу pvpkiran, который хорошо отвечает на вопрос об интеграционном тесте и позволяет начать его на правильном уровне: listUsers() или, возможно, выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...