วิธีตรวจสอบ stringified json ในสนธิสัญญา

ฉันกำลังพยายามสร้างข้อตกลงระหว่างสองบริการโดยใช้การสื่อสารแบบอะซิงโครนัส

นี่คือรหัสที่ฉันใช้ในการสร้างข้อตกลง:

@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "provider", providerType = ProviderType.ASYNCH)
public class StringifiedPactTest {

    @Pact(consumer = "consumer", provider = "provider")
    public MessagePact generatePact(MessagePactBuilder builder) {
        return builder.hasPactWith("provider")
                .expectsToReceive("A valid aws sns event")
                .withContent(new PactDslJsonBody().stringType(new String[]{"MessageId", "TopicArn"}).stringValue("Message", new PactDslJsonBody().stringType("Value", "Foo").toString()))
                .toPact();
    }

    @Test
    @PactTestFor(pactMethod = "generatePact")
    public void buildPact(List<Message> messages) {

    }
}

และสนธิสัญญาที่สร้างขึ้นก็คือ

{
  "consumer": {
    "name": "consumer"
  },
  "provider": {
    "name": "provider"
  },
  "messages": [
    {
      "description": "A valid aws sns event",
      "metaData": {
        "contentType": "application/json"
      },
      "contents": {
        "TopicArn": "string",
        "Message": "{\"Value\":\"Foo\"}",
        "MessageId": "string"
      },
      "matchingRules": {
        "body": {
          "$.MessageId": {
            "matchers": [
              {
                "match": "type"
              }
            ],
            "combine": "AND"
          },
          "$.TopicArn": {
            "matchers": [
              {
                "match": "type"
              }
            ],
            "combine": "AND"
          }
        }
      }
    }
  ],
  "metadata": {
    "pactSpecification": {
      "version": "3.0.0"
    },
    "pact-jvm": {
      "version": "4.0.10"
    }
  }
}

ซึ่งหมายความว่าผู้ผลิตควรมีข้อความที่ตรงกับ {Value : Foo} ชุดค่าผสมอื่นๆ เช่น {Value : Bar } จะไม่สำเร็จ มีวิธีใดในการเพิ่มกฎการจับคู่ภายใน json แบบ stringified หรือไม่? ขอบคุณ!


person Javier Molina Alonso    schedule 29.07.2020    source แหล่งที่มา


คำตอบ (2)


นี่คือตัวอย่างที่ไม่ระบุชื่อจากการทดสอบที่เรามี หวังว่ามันจะมีประโยชน์ สิ่งนี้จะสร้างข้อตกลงที่ตรงกับประเภทเท่านั้น ดังนั้นในด้านผู้ให้บริการ เมื่อฉันทดสอบกับสัญญา มันไม่สำคัญว่าฉันจะมีค่าอะไรสำหรับ categoryName ตราบใดที่มันเป็น stringType:

@PactTestFor(providerName = "provider-service", providerType = ProviderType.ASYNCH)
public class providerServiceConsumerPactTest {

    private static String messageFromJson;

    @BeforeAll
    static void beforeAll() throws Exception {
        messageFromJson = StreamUtils.copyToString(new ClassPathResource("/json/pact/consumer-service_provider-service.json").getInputStream(), Charset.defaultCharset());

    }

    @Pact(provider = "provider-service", consumer = "consumer-service")
    public MessagePact providerServiceMessage(MessagePactBuilder builder) {
        DslPart body = new PactDslJsonBody()
            .object("metaData")
                .stringType("origin", "provider-service")
                .datetimeExpression("dateCreated", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
            .closeObject()
            .minArrayLike("categories", 0, 1)
                .stringType("id", "example data")
                .stringType("categoryName", "example data")
                .booleanType("clearance", false)
                .closeObject()
            .closeArray();

        return builder
                .expectsToReceive("a provider-service update")
                .withContent(body)
                .toPact();
    }

    @Test
    @PactTestFor(pactMethod = "providerServiceMessage")
    public void testProviderServiceMessage(MessagePact pact) {

        // State

        final String messageFromPact = pact.getMessages().get(0).contentsAsString();

        // Assert

        JSONAssert.assertEquals(messageFromPact, messageFromJson, false);
    }
person wideawakewesley    schedule 30.07.2020

ฉันประสบปัญหาเดียวกันทุกประการ และน่าเสียดายที่ฉันไม่คิดว่าเป็นไปได้ที่จะบอก Pact ให้แยกวิเคราะห์ JSON ที่เป็นสตริงแล้วดูข้างใน (เช่นเพื่อตรวจสอบ parse(Message).Value === Foo ในตัวอย่างของคุณ)

วิธีที่ดีที่สุดที่คุณสามารถทำได้คือเขียนนิพจน์ทั่วไปให้ตรงกับสตริงที่คุณต้องการ เนื้อหาประเภทนี้แย่มากเพราะไม่มีวิธีง่ายๆ ที่จะเพิกเฉยต่อการจัดลำดับคีย์ JSON (เช่น "{\"a\":\"1\", \"b\":\"2\"}" และ "{\"b\":\"2\", \"a\":\"1\"}" จะเปรียบเทียบความแตกต่างกัน) แต่ AFAIK Pact ขาดฟังก์ชันการแยกวิเคราะห์ที่เรากำลังมองหา ดังนั้นเครื่องมือเดียวที่มีให้คือ regex

person Keenan Pepper    schedule 31.03.2021