契约测试(三)-- 代码实现篇(中)

背景:网上有不少介绍这种测试方法的概念和原理的文章,但实现的比较少。本文通过自己的方法从零开始搭建工程,实现了一个例子。在此也感谢朋友的帮助,是参考了TA的代码才能入了这道门。

环境:JDK1.8 + Gradle4.6 + Postgres9.6 + pact_broker

步骤:

这里接上一篇的步骤。契约测试(二)-- 代码实现篇(上)

四、立Consumer。Consumer中包括两个部分,一部分是定义自身需要的字段,另一部分是测试代码。

1. main->java->prduct_demo中有三个文件。

  • Product.java:定义Consumer端需要的数据类型。为了简化这里取名与Provider端相同,返回的数据类型字段定义也与Provider端相同。
  • ProductRestFetcher.java:获取数据。
  • Application.java:启动入口。

1)Product.java。与上一篇中Provider端的代码相同,这里不再赘述。

2)ProductFetcher.java

package product_demo;

import org.springframework.stereotype.Component;

import org.springframework.web.client.RestTemplate;

import java.net.URI;

@Component

public class ProductRestFetcher{

       public Product getProductInfo(URI providerUri) {

               RestTemplate restTemplate = new RestTemplate();

               return (Product)restTemplate.getForOjbect(providerUri, Product.class);

       }

}

3) Application.java。同Provider中Application.java,此处不再赘述。

2. test->java->product_demo中写测试文件。这里介绍了两种实现方式。

1)PactBaseConsumerTest.java

package product_demo;

import au.com.dius.pact.consumer.ConsumerPactTestMk2;

import au.com.dius.pact.consumer.MockServer;

import au.com.dius.pact.consumer.Pact;

import au.com.dius.pact.consumer.dsl.PactDslWithProvider;

import au.com.dius.pact.model.RequestResponsePact;

import org.junit.runner.RunWith;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;

import java.net.URI;

import java.util.HashMap;

import java.util.Map;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)

@SpringBootTest

public class PactBaseConsumerTest extends ConsumerPactTestMk2{

        @Override

        @Pact(provider = "Provider", consumer = "Consumer")

        public RequestResponsePact createPact(PactDslWithProvider builder){

               Map<String, String> headers = new HashMap<String, String>();

               headers.put("Content-Type", "application/json;charset=UTF-8");

               return builder

                                .given("")

                                .uponReceiving("My First Pact")

                                         .path("/api/v1/test")

                                         .query("")

                                         .method("GET")

                                .willRespondWith()

                                         .headers(headers)

                                         .status(200)

                                         .body("{" +

                                                  "\"code\": \"product.0\"," + 

                                                  "\"httpCode\": 200," + 

                                                  "\"msg\": \"ok\"," + 

                                                  "\"status\": true\n" + 

                                                  "}")

                                         .toPact();

        }

@Override

protected String providerName(){ return "Provider"; }

@Override

protected String consumerName(){ return "Consumer"; }

@Override

protected void runTest(MockServer mockServer) throws IOException{

      String url = mockServer.getUrl();

      URI productInfoUri = URI.create(String.format("%s%s", url, "/api/v1/test"));

      ProductRestFetcher productRestFetcher = new ProductRestFetcher();

      Product product = productRestFetcher.getProdcutInfo(productInfoUri);

      assertEquals("product.0", product.getCode());

     }

}

2)PactJunitDSLJsonBodyTest.java

package product_demo;

import au.com.dius.pact.consumer.ConsumerPactBuilder;

import au.com.dius.pact.consumer.PactVerificationResult;

import au.com.dius.pact.consumer.dsl.DslPart;

import au.com.dius.pact.consumer.dsl.PactDslJsonBody;

import au.com.dius.pact.model.MockProviderConfig;

import au.com.dius.pact.model.PactSpecVersion;

import au.com.dius.pact.model.RequestResponsePact;

import java.net.URI;

import java.util.HashMap;

import java.util.Map;

import static au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest;

import static org.junit.Assert.assertEquals;

public class PactJunitDSLJsonBodyTest{

        private void checkResult(PactVerificationResult result){

              if (result instanceof PactVerificationResult.Error) {

                    throw new RuntimeException(((PactVerificationResult.Error)result).getError());

               }

             assertEquals(PactVerificationResult.Ok.INSTANCE, result);

        }

@Test

public void testWithPactDSLJsonBody() {

          Map<String, String> headers = new HashMap<String, String>();

          headers.put("Content-Type", "application/json;charset=UTF-8");

          DslPart body = new PactDslJsonBody()

                    .stringType("code", "product.0")

                    .numberType("httpCode", 200)

                    .stringType("msg", "ok")

                    .booleanType("status", true)

                    .close();

      }

RequestResponsePact pact = ConsumerPactBuilder

                  .consumer("JunitDSLJsonBodyConsumer")

                  .hasPactWith("Provider")

                  .given("")

                  .uponReceiving("My First Pact Test")

                           .path("/api/v1/test")

                           .query("")

                           .method("GET")

                   .willRespondWith()

                           .headers(headers)

                           .status(200)

                           .body(body)

                   .toPact();

   MockProviderConfig config = MockProviderConfig.createDefault(PactSpecVersion.V3);

   PactVerificationResult result = runConsumerTest(pact, config, mockServer -> {

              String url = mockServer.getUrl();

              URI productInfoUri = URI.create(String.format("%s%s", url, "/api/v1/test"));

              Product product = new ProductRestFetcher().getProductInfo(productInfoUri);

              assertEquals("product.0", product.getCode());

             });

    checkResult(result);

  }

}

五、配置Consumer中的build.gradle文件。

...  // 头部省略

buildscript {
    repositories {
        mavenCentral()            // maven仓库
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")            // gradle插件
        classpath("org.thymeleaf:thymeleaf:3.0.8.RELEASE")                              // springboot工程的starter之一
        classpath("au.com.dius:pact-jvm-provider-gradle_2.12:3.5.10")             // provider插件
    }
}

apply plugin: 'java'

apply plugin: 'idea'

apply plugin: 'org.springframework.boot'

apply plugin: 'au.com.dius.pact'

jar {
        baseName = 'Consumer'
        version =  '1.0.0'
}

  sourceCompatibility = 1.8
  targetCompatibility = 1.8

test{

       systemProperties['pact.rootDir'] = "$rootDir/target/pacts"

}

repositories {
        mavenCentral()
}

dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
        compile("org.springframework.boot:spring-boot-starter-thymeleaf")
        compile("org.springframework.boot:spring-boot-devtools")
        testCompile('org.springframework.boot:spring-boot-starter-test')
        testCompile group: 'junit', name: 'junit', version: '4.1.2'
        testCompile("au.com.dius:pact-jvm-consumer-junit_2.12:3.5.12")
        testCompile("au.com.dius:pact-jvm-consumer-java8_2.12:3.5.12")
 }

 pact {           // 定义pact,固定格式
        publish{                // 定义pact,固定格式

                pactDirectory = "$rootDir/target/pacts"
            }

}

到此,Provider和Consumer端的代码和配置都完成了,下一篇将介绍测试的过程。

参考资料:

1. https://docs.pact.io/

2. https://www.jianshu.com/p/681047496728

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值