2017-09-22 8 views
1

私はpact-JVMを使用して2つのサービスの間で契約を生成しようとしています。しかし、Javaクラスを実行しようとすると、この例外が発生します。pact-jvm:au.com.dius.pact.consumer.PactMismatchesExceptionを解決する方法

1)私はPact本体に何か問題があると思われますが、それは間違いありませんか? PactDslWithProviderのJSON本体に余分な 'message'パラメータがありますが、runTest1()メソッドではリストのみを比較しています。結果を調べると、私と同じです。 2)runTest1()メソッドで実際のプロバイダURLを指定するのは正しいですか?私はちょうど私が@Ruleをコメントアウト場合ことがわかっ

以下
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)); 

} 

}

EDITです(プロバイダが所定の位置にすでにあります)テストは合格ですが、パクトファイルは生成されません。 Shouod私は明示的に "pact"フォルダを指定していますか?

答えて

1

私は、テストが実行された後に生成されない協定に関する同様の問題がありました。私は注釈アプローチを使用して作業することはできませんでしたが、代わりにConsumerPactTestMk2を拡張して解決しました。パクトはモックサーバーをセットアップし、あなたのためにレスポンスをモックします。

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を追加する必要がありました。しかし、それは良い作品です。

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

あなたは私の一日を作った:)それは魅力のように働いた。ちょうど1つのことは、私はguavaの依存関係を追加する必要はありませんでした。これは、依存関係なしにpactファイルを生成しました。 – ljs

+0

これを使用して複数のプロバイダを指定することはできますか?ありがとう.. – ljs

+0

はい、サービスが使用するプロバイダごとに異なるテストを作成できます。または、コンシューマがプロバイダからの複数のエンドポイントを消費する場合、createPactメソッドに複数のテストケースを追加できます。また、春の雲を使用している場合は、グアバ19を追加する必要があります。 – ertert

1

テストにはいくつか問題があります。あなたが協定プロバイダルールのポートを指定していないので、それはランダムなポート上でモックサーバーを起動さ

問題#1

。あなたのテストはポート8091でプロバイダにアクセスしているので、Pactはテストに失敗し、期待したリクエストが得られなかったことを報告します(リクエストはポート8091でリッスンしています)。

これを解決するには、ルールにポート8091を指定するか(8091で実行中のものをシャットダウンする必要があります)、またはクライアントにモックサーバーのポートを使用させる(getMockServer().getPort()から呼び出してください)。

問題#2

あなたのテストでは、それは本当に春HTTPクライアントとBeanデシリアライズ以外のものをテストしていないことを意味する、直接春休憩テンプレートを使用しています。使用しているクライアントコード(つまり、残りのテンプレートを使用するクラス)を使用し、テストで呼び出す必要があります。

+0

問題2の場合:私の場合、消費者は実際にはコントローラサービス構造のスプリングプロジェクトです。また、単体テストでは、MockRestServiceServerを使用して、このURLが行う特定のメソッドを呼び出します。 'mockServer = MockRestServiceServer.createServer(restTemplate);' そして 'mockServer.expect(requestTo(CoreMatchers.containsString(config.getDeviceResource)))) .andExpect(メソッド(HttpMethod.GET);'それはあなたが言ったことですか?私はやっているはずですか? – ljs

+0

私は春のコントローラサービス構造に多くのコンテキストを持っていませんが、そのメソッドが正しいものになると思います。 –

関連する問題