主要用於在微服務架構下作CDC(消費者驅動契約)測試。下圖展現了多個微服務的調用,若是咱們更改了一個模塊要如何進行測試呢?java
模擬一個股票價格查詢的服務git
springcloud-contract-provider-restgithub
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-contract-verifier</artifactId> <scope>test</scope> </dependency> <build> <plugins> <plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>2.2.1.RELEASE</version> <extensions>true</extensions> <configuration> <!--用於構建過程當中插件自動生成測試用例的基類--> <baseClassForTests> com.example.springcloudcontractproviderrest.RestBaseCase </baseClassForTests> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
既然是消費者驅動契約,我麼首先須要制定契約,這裏爲了方便假設查詢貴州茅臺的股價返回值是固定的999,也能夠經過正則等方式去限制返回值spring
Contract.make { description "query by id should return stock(id,price)" request { method GET() url value { // 消費者使用時請求任何 /stock/price/數字 都會被轉爲 /stock/price/600519 consumer regex('/stock/price/\\d+') producer "/stock/price/600519" } } response { status OK() headers { contentType applicationJson() } // 提供給消費者的默認返回 body([ id : 600519, price: 999 ]) // 服務端在測試過程當中,body須要知足的規則 bodyMatchers { jsonPath '$.id', byRegex(number()) jsonPath '$.price', byRegex(number()) } } }
主要是加載環境,而後因爲不是真實環境模擬了數據庫查詢數據庫
@SpringBootTest @RunWith(SpringRunner.class) public class RestBaseCase { @Autowired private StockController stockController; @MockBean private StockRepository stockRepository; @Before public void setup() { init(); RestAssuredMockMvc.standaloneSetup(stockController); } private void init() { Mockito.when(stockRepository.getStockById(600519)).thenReturn(new StockDTO(600519, "貴州茅臺", 999L, "SH")); } }
實現咱們的服務功能,具體代碼邏輯能夠在項目地址中查看,而後測試看是否符合契約json
mvn clean test
架構
能夠在生成(target)目錄中找到 generated-test-sources 這個目錄,插件爲咱們自動生成而且運行的case就在其中app
public class StockTest extends RestBaseCase { @Test public void validate_shoudReturnStockIdAndPrice() throws Exception { // given: MockMvcRequestSpecification request = given(); // when: ResponseOptions response = given().spec(request) .get("/stock/price/600519"); // then: assertThat(response.statusCode()).isEqualTo(200); assertThat(response.header("Content-Type")).matches("application/json.*"); // and: DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); // and: assertThat(parsedJson.read("$.id", String.class)).matches("-?(\\d*\\.\\d+|\\d+)"); assertThat(parsedJson.read("$.price", String.class)).matches("-?(\\d*\\.\\d+|\\d+)"); } }
若是一切順利就能夠deploy了maven
模擬查詢我的資產的服務,須要遠程調用股票價格查詢服務,計算總資產ide
springcloud-contract-consumer-rest
編寫測試用例驗證服務
@SpringBootTest @RunWith(SpringRunner.class) @AutoConfigureStubRunner( ids = {"com.example:springcloud-contract-provider-rest:+:stubs:8880"}, stubsMode = StubRunnerProperties.StubsMode.LOCAL ) public class StockApiTest { @Autowired private StockApi stockApi; @Test public void testStockApi() throws IOException { StockPriceDTO stockPrice = stockApi.getStockPrice(600519).execute().body(); BDDAssertions.then(stockPrice.getId()).isEqualTo(600519); BDDAssertions.then(stockPrice.getPrice()).isEqualTo(999); } }