java - 当数据返回带或不带子项的项目(填充或不存在现有数组)时如何验证 PACT

标签 java 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();
}

非常感谢。

最佳答案

对你的问题的简短回答是,没有办法完全按照你想要的方式去做。

关于为什么不可用的较长答案位于常见问题解答中:

为什么不支持指定可选属性?

首先,假设您在进行验证测试时可以控制提供者的数据(和消费者的数据)。如果你不这样做,那么 Pact 可能是 not the best tool for your situation .

其次,如果 Pact 支持断言元素 $.body.name 可能出现在响应中,那么您编写的消费者代码可以处理可选的 $.body.name ,但事实上,提供者给出了$.body.firstname,任何测试都不会告诉您您做出了错误的假设。请记住,提供商可以在不违反契约(Contract)的情况下返回额外的数据,但它必须至少提供您期望的数据。

指定“SOME_VALUE 或 null”也是如此。如果您的所有提供商验证测试数据都为此 key 返回空值,您可能会认为您已经验证了“SOME_VALUE”,但事实上,您从未验证过。您可能会在生产中为该 key 获得完全不同的“SOME_VALUE”,这可能会导致问题。

对于指定长度为 0 或更大的数组也是如此。如果您的所有提供者验证数据都返回 0 长度数组,则所有验证测试都将通过,而无需您验证数组的内容。这就是为什么您只能指定最小长度为 1 的数组或零长度数组。

请记住,与描述文档所有可能状态的模式不同,Pact 是“通过示例进行契约”。如果您需要断言可能有多种变体,那么您需要为每个变体提供一个示例。不过,在为每个变体添加 Pact 测试之前,请考虑一下它对您是否真的很重要。请记住,每次交互都会带来维护和执行时间的“成本”,您需要考虑在您的特定情况下是否值得付出这些成本。您可能最好处理协议(protocol)中的常见场景,然后将您的消费者编写代码以优雅地处理意外变化(例如,通过忽略该数据并发出警报)。

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

关于java - 当数据返回带或不带子项的项目(填充或不存在现有数组)时如何验证 PACT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61772433/

相关文章:

java - nextInt(int) 对于 Random 类型是未定义的

java - PACT 用于 JSON 整数数组

gradle - Pact Gradle 状态 url 响应

java - Activity 无法转移到 onclicklistener

java - Storm : eventhub spout stops receiving messages

java - Stanford-NLP:找不到主类错误

Java/Android : When I put a ScrollView - I get a soft keyboard. 布局不好

go - 提供者未注册交互

javascript - Pact 模拟服务器未返回正确的 CORS header