PACT-JVM:如何求解Au.com.dius.pact.consumer.pactmistsexexception



我正在尝试使用PACT-JVM在我们的2个服务之间生成契约。但是,当我尝试运行Java类时,我会得到此例外。

1)我怀疑协议主体有什么问题,是正确的吗?pactdslwithprovider的JSON主体中有一个额外的"消息"参数,但是在runtest1()方法中,我仅等同于列表,当我检查结果时,它们对我来说是相同的。2)在Runtest1()方法中提供实际提供商URL是否正确?(提供商已经到位)

au.com.dius.pact.consumer.PactMismatchesException: The following requests were not received:
method: GET
path: /devices/v1
query: [externalId:[0942dc67-35de-44f7-a061-743f59436a98]]
headers: [:]
matchers: MatchingRules(rules=[:])
generators: Generators(categories={})
body: OptionalBody(state=MISSING, value=null)

下面是我的Java类

public class PactForDevice {
    Map<String, String> headers = MapUtils.putAll(new HashMap<String, String>(), new String[]{"Content-Type", "application/json;charset=UTF-8"});
@Rule
public PactProviderRuleMk2 provider = new PactProviderRuleMk2("device-service-m", this);
@Pact(consumer = "device-r", provider = "device-service-m")
public RequestResponsePact createFragment(PactDslWithProvider builder) {
    return builder
            .given("Device M details")
            .uponReceiving("retrieving Device details")
            .path("/devices/v1")
            .method("GET")
            .query("externalId=0942dc67-35de-44f7-a061-743f59436a98")
            .willRespondWith()
            .headers(headers)
            .status(200)
            .body("{" +
                    ""data": [,n " +
                    "{ n" +
                    " "dateRegistered": "2017-07-13T11:10:51.000+12:00",n" +
                    " "alias": "",n" +
                    " "id": "a02b14ee72192ab3",n" +
                    " "description": "Samsung SM-G930F",n" +
                    " "title": "a02b14ee72192ab3",n" +
                    " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                    "},n" +
                    "{n" +
                    " "dateRegistered": "2017-07-13T10:45:51.000+12:00",n" +
                    " "alias": "",n" +
                    " "id": "a41c3af56ec35874",n" +
                    " "description": "Samsung SM-T819",n" +
                    " "title": "a41c3af56ec35874",n" +
                    " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                    " },n" +
                    " {n" +
                    " "dateRegistered": "2017-07-13T10:45:31.000+12:00",n" +
                    " "alias": "",n" +
                    " "id": "bd2b027bbd0a2f17",n" +
                    " "description": "Samsung SM-A320Y",n" +
                    " "title": "bd2b027bbd0a2f17",n" +
                    " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                    " }n" +
                    "],n" +
                    " "message": "3 devices found for the user 0942dc67-35de-44f7-a061-743f59436a98"n" +
                    "}")
            .toPact();
}
@PactVerification("device-service-m")
@Test
@JsonIgnoreProperties(ignoreUnknown = true)
public void runTest1() throws IOException {
    final GetDevicesResponse deviceResponse = new GetDevicesResponse();
    final List<Device> deviceList = new ArrayList<>();
    Device dev = new Device();
    dev.withDateRegistered("2017-07-13T11:10:51.000+12:00");
    dev.withAlias("");
    dev.withId("a02b14ee72192ab3");
    dev.withDescription("Samsung SM-G930F");
    dev.withTitle("a02b14ee72192ab3");
    dev.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
    deviceList.add(dev);
    Device dev1 = new Device();
    dev1.withDateRegistered("2017-07-13T10:45:51.000+12:00");
    dev1.withAlias("");
    dev1.withId("a41c3af56ec35874");
    dev1.withDescription("Samsung SM-T819");
    dev1.withTitle("a41c3af56ec35874");
    dev1.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
    deviceList.add(dev1);
    Device dev2 = new Device();
    dev2.withDateRegistered("2017-07-13T10:45:31.000+12:00");
    dev2.withAlias("");
    dev2.withId("bd2b027bbd0a2f17");
    dev2.withDescription("Samsung SM-A320Y");
    dev2.withTitle("bd2b027bbd0a2f17");
    dev2.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
    deviceList.add(dev2);
    deviceResponse.setDevices(deviceList);
    final RestTemplate restTemplate = new RestTemplate();
    GetDevicesResponse devices = restTemplate.getForObject("http://localhost:8091/devices/v1?externalId=0942dc67-35de-44f7-a061-743f59436a98", GetDevicesResponse.class);
    assertThat(devices, sameBeanAs(deviceResponse));
}  

}

编辑:

我刚刚发现,如果我评论@Rule部分,则测试将通过 - 但是PACT文件不会生成。我明确指定了一个" pact"文件夹?

测试有一些问题。

问题#1

您尚未指定PACT提供商规则的端口,因此它正在随机端口上启动模拟服务器。您的测试正在端口8091上访问您的提供商,因此PACT未能通过测试,并报告没有得到预期请求,但该请求未达到(该请求是在端口8091上听到的)。

您可以通过向规则提供端口8091来解决此问题(您需要关闭在8091上运行的任何内容),或者让客户端使用模拟服务器的端口(通过调用getMockServer().getPort())。

问题#2

您的测试直接使用Spring Rest模板,这意味着除了Spring HTTP客户端和Bean De-Serialisation以外,它并没有真正测试其他任何内容。您应该使用所拥有的任何客户端代码(即使用休息模板的类),并在测试中调用。

我也有类似的问题,在测试后未生成条约。我从来没有让他们使用注释方法上班,而是通过扩展ConsumerPactTestMk2解决了它。PACT将设置模型服务器并为您模拟响应。

public class PactForDevice extends ConsumerPactTestMk2 {
    Map<String, String> headers = MapUtils.putAll(new HashMap<String, String>(), new String[]{"Content-Type", "application/json;charset=UTF-8"});
    public RequestResponsePact createPact(PactDslWithProvider builder) {
        return builder
          .given("Device M details")
          .uponReceiving("retrieving Device details")
          .path("/devices/v1")
          .method("GET")
          .query("externalId=0942dc67-35de-44f7-a061-743f59436a98")
          .willRespondWith()
          .headers(headers)
          .status(200)
          .body("{" +
                ""data": [,n " +
                "{ n" +
                " "dateRegistered": "2017-07-13T11:10:51.000+12:00",n" +
                " "alias": "",n" +
                " "id": "a02b14ee72192ab3",n" +
                " "description": "Samsung SM-G930F",n" +
                " "title": "a02b14ee72192ab3",n" +
                " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                "},n" +
                "{n" +
                " "dateRegistered": "2017-07-13T10:45:51.000+12:00",n" +
                " "alias": "",n" +
                " "id": "a41c3af56ec35874",n" +
                " "description": "Samsung SM-T819",n" +
                " "title": "a41c3af56ec35874",n" +
                " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                " },n" +
                " {n" +
                " "dateRegistered": "2017-07-13T10:45:31.000+12:00",n" +
                " "alias": "",n" +
                " "id": "bd2b027bbd0a2f17",n" +
                " "description": "Samsung SM-A320Y",n" +
                " "title": "bd2b027bbd0a2f17",n" +
                " "externalId": "0942dc67-35de-44f7-a061-743f59436a98"n" +
                " }n" +
                "],n" +
                " "message": "3 devices found for the user 0942dc67-35de-44f7-a061-743f59436a98"n" +
                "}")
        .toPact();
    }
    @Override
    protected String providerName() {
        return "device-service-m";
    }
    @Override
    protected String consumerName() {
        return "device-r";
    }
    @Override
    protected void runTest(MockServer mockServer) throws IOException {
        final GetDevicesResponse deviceResponse = new GetDevicesResponse();
        final List<Device> deviceList = new ArrayList<>();
        Device dev = new Device();
        dev.withDateRegistered("2017-07-13T11:10:51.000+12:00");
        dev.withAlias("");
        dev.withId("a02b14ee72192ab3");
        dev.withDescription("Samsung SM-G930F");
        dev.withTitle("a02b14ee72192ab3");
        dev.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
        deviceList.add(dev);
        Device dev1 = new Device();
        dev1.withDateRegistered("2017-07-13T10:45:51.000+12:00");
        dev1.withAlias("");
        dev1.withId("a41c3af56ec35874");
        dev1.withDescription("Samsung SM-T819");
        dev1.withTitle("a41c3af56ec35874");
        dev1.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
        deviceList.add(dev1);
        Device dev2 = new Device();
        dev2.withDateRegistered("2017-07-13T10:45:31.000+12:00");
        dev2.withAlias("");
        dev2.withId("bd2b027bbd0a2f17");
        dev2.withDescription("Samsung SM-A320Y");
        dev2.withTitle("bd2b027bbd0a2f17");
        dev2.withExternalId("0942dc67-35de-44f7-a061-743f59436a98");
        deviceList.add(dev2);
        deviceResponse.setDevices(deviceList);
        String url = mockServer.getUrl();
        String path = "devices/v1";
        String query = "externalId=0942dc67-35de-44f7-a061-743f59436a98";
        URIBuilder uriBuilder = null;
        try {
            uriBuilder = new URIBuilder(url)
                                .setPath(path)
                                .setQuery(query);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        GetDevicesResponse devices = new ObjectMapper().readValue(Request.Get(uriBuilder.toString())
                .addHeader("content-type", "application/json")
                .execute().returnContent().asString(), GetDevicesResponse.class);
        assertThat(devices, sameBeanAs(deviceResponse));
    }
}

使用这种方法,我不得不将Google Guava 19添加到我的POM中。但是它效果很好。

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>19.0</version>
</dependency>

相关内容

  • 没有找到相关文章

最新更新