CDC - Pact: Simple Usage

Usage: Java + Sprint Boot + Maven + Junit,please refer for detail:Github - cdc-pact

pact-provider

Implemetion: return name and age(<6) by passing parameter name

  • Provider Model

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class ProviderModel {
    String name;
    Integer age;

    public ProviderModel(String name, int age) {
    this.name = name;
    this.age = age;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    }
  • Provider Control

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RestController
    public class ProviderController {

    @RequestMapping("/person/{name}")
    public ProviderModel person(@PathVariable String name){
    int age = new Random().nextInt(6);

    return new ProviderModel(name, age);
    }
    }

pact-consumer

  • pom.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.izheyi</groupId>
    <artifactId>pact-consummer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>pact-consummer</name>
    <url>http://maven.apache.org</url>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
    </dependency>

    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.json/json -->
    <dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180813</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/au.com.dius/pact-jvm-consumer-junit -->
    <dependency>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-consumer-junit_2.12</artifactId>
    <version>3.5.24</version>
    <scope>test</scope>
    </dependency>
    </dependencies>
    </project>
  • call provider(test)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public class GetPersonAge{
    int port = 8080;

    public GetPersonAge(String url) {
    // TODO Auto-generated constructor stub
    }

    public GetPersonAge() {
    // TODO Auto-generated constructor stub
    }

    public static void main(String[] args) {
    Integer age = new GetPersonAge().checkAge("zhangsan");
    System.out.println("Age is: " + age);
    }

    public Integer checkAge(String name) {

    try {
    String url = String.format("http://localhost:%d/person/%s", port, name);
    System.out.println("URL is: " + url);

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(url);
    String json = null;

    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();
    if (entity != null) {
    json = EntityUtils.toString(entity, "UTF-8").trim();
    }

    System.out.println("Json is: " + json);
    JSONObject jsonObject = new JSONObject(json);
    String age = jsonObject.get("age").toString();
    return new Integer(age);

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return null;
    }
    }

    }
  • consumer pact test

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public class ConsumerTest {

    @Rule
    public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("test_provider", "localhost", 8080, this);

    @Pact(provider="test_provider", consumer="test_consumer")
    public RequestResponsePact createPact(PactDslWithProvider builder) {
    Map<String, String> headers = new HashMap<String, String>();
    headers.put("Content-Type", "application/json");

    DslPart resbody = new PactDslJsonBody()
    .stringType("name", "zhangsan")
    .integerType("age", 5)
    .asBody();

    return builder
    .uponReceiving("A request for age for person zhangsan")
    .path("/person/zhangsan")
    .method("GET")
    .willRespondWith()
    .status(200)
    .headers(headers)
    .body(resbody)
    .toPact();
    }

    @Test
    @PactVerification()
    public void doTest(){
    Integer age = new GetPersonAge(mockProvider.getUrl()).checkAge("zhangsan");
    System.out.println("Test result, age = " + age);
    assertTrue(age <= 6);
    }
    }

cdc process with pact

  1. Run Junit pact test in consumer.
  2. Generate contract file(test_consumer-test_provider.json) to trget automatically.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    {
    "provider": {
    "name": "test_provider"
    }
    ,

    "consumer": {
    "name": "test_consumer"
    }
    ,

    "interactions": [
    {
    "description": "A request for age for person zhangsan",
    "request": {
    "method": "GET",
    "path": "/person/zhangsan"
    }
    ,

    "response": {
    "status": 200,
    "headers": {
    "Content-Type": "application/json"
    }
    ,

    "body": {
    "name": "zhangsan",
    "age": 5
    }
    ,

    "matchingRules": {
    "body": {
    "$.name": {
    "matchers": [
    {
    "match": "type"
    }

    ],

    "combine": "AND"
    }
    ,

    "$.age": {
    "matchers": [
    {
    "match": "integer"
    }

    ],

    "combine": "AND"
    }

    }

    }

    }

    }

    ],

    "metadata": {
    "pactSpecification": {
    "version": "3.0.0"
    }
    ,

    "pact-jvm": {
    "version": "3.5.24"
    }

    }

    }

  3. Add the below in provider pom

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <plugin>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-provider-maven_2.12</artifactId>
    <version>3.5.24</version>
    <configuration>
    <serviceProviders>
    <!-- You can define as many as you need, but each must have a unique name -->
    <serviceProvider>
    <name>test_provider</name>
    <!-- All the provider properties are optional, and have sensible defaults (shown below) -->
    <protocol>http</protocol>
    <host>localhost</host>
    <port>8080</port>
    <path>/</path>
    <consumers>
    <!-- Again, you can define as many consumers for each provider as you need, but each must have a unique name -->
    <consumer>
    <name>test_consumer</name>
    <!-- currently supports a file path using pactFile or a URL using pactUrl -->
    <pactFile>../pact-consumer/target/pacts/test_consumer-test_provider.json</pactFile>
    </consumer>
    </consumers>
    </serviceProvider>
    </serviceProviders>
    </configuration>
    </plugin>
  4. Start the provider application.

  5. Run mvn pact:verify
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    D:\Java\pact\pact-jvm\pact-provider>mvn pact:verify
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ----------------------< com.izheyi:pact-provider >----------------------
    [INFO] Building pact-provider 0.0.1-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO]
    [INFO] --- pact-jvm-provider-maven_2.12:3.5.24:verify (default-cli) @ pact-provider ---

    Verifying a pact between test_consumer and test_provider
    [Using File ..\pact-consumer\target\pacts\test_consumer-test_provider.json]
    A request for age for person zhangsan
    returns a response which
    has status code 200 (OK)
    includes headers
    "Content-Type" with value "application/json" (OK)
    has a matching body (OK)
    [WARNING] Skipping publishing of verification results as it has been disabled (pact.verifier.publishResults is not 'true')
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 7.577 s
    [INFO] Finished at: 2018-11-13T09:09:01+08:00
    [INFO] ------------------------------------------------------------------------
唐胡璐 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
分享创造价值,您的支持将鼓励我继续前行!