Как проверить PACT, когда данные возвращают элементы с дочерними элементами или без них (заполненный или не существующий массив)

Я использую PACT и Java для контрактных тестов, и моя проблема в том, что у меня есть API, в котором элементы могут появляться следующим образом:

[
 {
  "programCode": "ELA_NGL_G7_TX",
  "contentResources": [
    {
        "tocPosition": 1827,
        "contentIdentifier": "l_6bf0783e-8499-4f6c-9f9b-c8fbdc8dcf6b_e5f25016-e2fa-4223-8969-2004c644917d"
    },
    {
        "tocPosition": 1828,
        "contentIdentifier": "l_192af774-54b9-4280-87e9-71f2b86a7d4d_e5f25016-e2fa-4223-8969-2004c644917d",
        "skills": [
            {
                "skillId": "ae836bd9-4758-4665-b3f8-8339313363e3",
                "spineId": "63c2b7d0-cd69-4e8a-9761-c90623104b8c"
            }
        ]
    }
]

Итак, как вы можете видеть, иногда внутренний массив навыков появляется, а иногда нет, и я не знаю, как включить этот сценарий в мои потребительские тесты. Я имею в виду, что если бы в ответе был массив навыков или его не было в зависимости от конкретных параметров, у меня могло бы быть два разных теста, и это могло бы быть хорошо, но здесь они исходят из одного и того же вызова. Итак, я предполагаю, что мне нужно что-то вроде if else, что если массив навыков присутствует, то я бы утвердил его внутренних дочерних элементов, иначе просто проигнорировал бы его.

Это мой потребитель:

@ExtendWith(PactConsumerTestExt.class)
public class PublishContractWithTocGetSummaryTest {

Map<String, String> headers = new HashMap<>();

String getRecommendations = "/toc/getsummary/ELA_NGL_G7_TX";

@Pact(provider = "CRS-METADATA-FILTERING-SERVICE", consumer = "CRS-TOC-RECOMMENDER")
public RequestResponsePact createPact(PactDslWithProvider builder) throws IOException {

    headers.put("Content-Type", "application/json");

    DslPart body = new PactDslJsonBody()
            .stringValue("programCode", "ELA_NGL_G7_TX")
            .eachLike("contentResources")
                .integerType("tocPosition", 0)
                .stringType("contentIdentifier", "l_9d23cb4f-69dc-4032-bb53-73501234dc14_e5f25016-e2fa-4223-8969-2004c644917d")
            .closeArray();

    return builder
            .given("get TOC Summary")
            .uponReceiving("get TOC Summary")
            .path(getRecommendations)
            .method("GET")
            .headers(headers)
            .willRespondWith()
            .status(200)
            .body(body)
            .toPact();
}

Большое спасибо.


person Francislainy Campos    schedule 13.05.2020    source источник


Ответы (2)


Короткий ответ на ваш вопрос заключается в том, что нет способа сделать именно то, что вы хотите.

Более длинный ответ о том, почему это недоступно, находится в часто задаваемых вопросах:

Почему нет поддержки указания необязательных атрибутов?

Во-первых, предполагается, что вы контролируете данные поставщика (и данные потребителя) при выполнении проверочных тестов. Если нет, то, возможно, Pact не лучший инструмент для вашей ситуации.

Во-вторых, если Pact поддерживает утверждение о том, что элемент $.body.name может присутствовать в ответе, то вы пишете потребительский код, который может обрабатывать необязательный $.body.name, но на самом деле поставщик предоставляет $.body.firstname, и ни один тест никогда не подведет вас, чтобы сказать вам, что вы мы сделали неверное предположение. Помните, что провайдер может вернуть дополнительные данные без нарушения контракта, но он должен предоставить как минимум те данные, которые вы ожидаете.

То же самое касается указания «SOME_VALUE или null». Если все проверочные данные вашего провайдера возвращают для этого ключа значения NULL, вы можете подумать, что вы проверили "SOME_VALUE", но на самом деле это не так. Вы можете получить совершенно другое «SOME_VALUE» для этого ключа в рабочей среде, что может вызвать проблемы.

То же самое касается указания массива длиной 0 или более. Если бы все данные проверки вашего провайдера возвращали массивы нулевой длины, все ваши проверочные тесты прошли бы без проверки содержимого массива. Вот почему вы можете указать только массив с минимальной длиной 1 ИЛИ массив с нулевой длиной.

Помните, что в отличие от схемы, описывающей все возможные состояния документа, Pact — это «договор на примерах». Если вам нужно утверждать, что возможны несколько вариантов, вам нужно предоставить пример для каждого из этих вариантов. Однако подумайте, действительно ли это важно для вас, прежде чем добавлять тест Pact для каждого варианта. Помните, что каждое взаимодействие сопряжено с «стоимостью» обслуживания и времени выполнения, и вам необходимо подумать, стоит ли оно затрат в вашей конкретной ситуации. Возможно, вам будет лучше обработать распространенные сценарии в пакте, а затем написать вашему потребителю код для изящной обработки неожиданных изменений (например, игнорируя эти данные и вызывая предупреждение).

https://docs.pact.io/faq#why-is-there-no-support-for-specifying-Optional-Attributes

person Beth Skurrie    schedule 13.05.2020

Итак, TL; DR ответа Бет:

  1. Решите, что ценно для тестирования — пустые массивы, непустые или и то, и другое.
  2. Используйте состояния поставщика, чтобы указать любые варианты ответа (потребительский тест)
  3. Реализуйте состояние для теста провайдера, чтобы иметь возможность контролировать ответ
person Matthew Fellows    schedule 13.05.2020