AMQ 消息的 V3.0 合约中的字符串类型匹配器进行文字匹配而不是类型匹配

stringType matcher in V3.0 contract for AMQ message does a literal match instead of type-matching

我有一个使用 stringType 来匹配文件名的合同。合同还在类型上指定了匹配器,但是当我 运行 在提供者端进行测试时,它会进行文字匹配。我已经包含了合同、发送的 JSON 和调试时的屏幕截图。我注意到在 MatchingRuleGroup 中初始化了一个 TypeMatcher,但它没有字段。我不确定这是否正确

我尝试了 3 种情况:

我使用的供应商

pact-jvm-provider-spring_2.12 - 版本 3.6.2

我在消费者那里使用

pact-jvm-consumer-junit_2.12 - 版本 3.6.2

pact-jvm-consumer-java8_2.12 - 版本 3.6.2

合同:

{
    "consumer": {
        "name": "Consumer-event"
    },
    "provider": {
        "name": "Provider"
    },
    "messages": [
        {
            "description": "A message notifying a newly available foo file",
            "metaData": {
                "bestandstype": "foo",
                "Content-Type": "application/json"
            },
            "contents": {
                "headers": {
                    "bestandstype": "foo",
                    "Content-Type": "application/json"
                },
                "payload": {
                    "bestandstype": "foo",
                    "bestandsid": "string"
                }
            },
            "providerStates": [
                {
                    "name": "A new FOO file is extracted"
                }
            ],
            "matchingRules": {
                "body": {
                    "$.payload$.bestandsid": {
                        "matchers": [
                            {
                                "match": "type"
                            }
                        ],
                        "combine": "AND"
                    }
                }
            }
        }
    ],
    "metadata": {
        "pactSpecification": {
            "version": "3.0.0"
        },
        "pact-jvm": {
            "version": "3.6.2"
        }
    }
}

实际事件

{
    "headers": {
        "Content-Type": "application/json",
        "bestandstype": "foo",
        "id": "6838a619-efb7-6867-28bc-eb24609aa980",
        "timestamp": 1560410882485
    },
    "payload": {
        "afleidDatum": null,
        "bestandsid": "20190219_foo_20190124.txt",
        "bestandstype": "foo",
        "bron": null,
        "planDatum": null,
        "planType": "BAR"
    }
}

消费者合同

    @Pact(provider = "DonnaFileshareReader", consumer = "DpcAdapter-event")
    public MessagePact eventNewDpcResource(MessagePactBuilder builder) {

        Map<String, String> metadata = new HashMap<>();
        metadata.put("Content-Type", "application/json");
        metadata.put("bestandstype", "dpc");

        PactDslJsonBody body = new PactDslJsonBody();
        body.object("headers")
            .stringValue("bestandstype", "dpc")
            .stringValue("Content-Type", "application/json")
            .closeObject();
        payload = new PactDslJsonBody();
        payload.stringValue("bestandstype", "dpc")
               .stringValue("bestandsid", EXAMPLE_DPC_FILE_NAME)
               .closeObject();
        body.object("payload", payload);

        return builder.given("A new DPC file is extracted")
                      .expectsToReceive("A message notifying a newly available dpc file")
                      .withMetadata(metadata)
                      .withContent(body)
                      .toPact();
    }

错误:


Verifying a pact between DpcAdapter-event and DonnaFileshareReader
  Given A new FOO file is extracted
  A message notifying a newly available foo file
2019-06-13 09:56:54.144  INFO [bar,,,] 7427 --- [           main] org.reflections.Reflections              : Reflections took 9011 ms to scan 388 urls, producing 275 keys and 35566 values 
    generates a message which
      has a matching body (FAILED)
      has matching metadata (OK)

Failures:

0) A message notifying a newly available foo file generates a message which has a matching body
      $.payload.bestandsid -> Expected 'string' but received '20190219_foo_20190124.txt'

调试

我希望 stringType 匹配 String 类型。

已解决。

通过将合同更改为 1 PactDslJsonBody() 而不是使用 body(object,payload)。

新合同:

body.object("headers")
                .stringValue("bestandstype", "foo")
                .stringValue("Content-Type", "application/json")
                .closeObject();
        body.object("payload")
                .stringValue("bestandstype", "foo")
                .stringType("bestandsid", EXAMPLE_FOO_FILE_NAME)
                .closeObject();

测试中的新消息构造(尽管您也可以像在原始问题中那样构造 PactDslJsonBody 并使用它)

        JSONObject resourceDetail = (JSONObject)body.getBody();
        JSONObject payload = resourceDetail.getJSONObject("payload");

        Message<byte[]> pactMessage = MessageBuilder
                .withPayload(payload.toString().getBytes())
                .copyHeaders(messageProvider.getMetadata())
                .build();