Въведение в пролетния облачен договор

1. Въведение

Spring Cloud Contract е проект, който, просто казано, ни помага да напишем потребителски договори (CDC).

Това гарантира договора между производител и потребител в разпределена система - както за HTTP-базирани, така и за базирани на съобщения взаимодействия.

В тази кратка статия ще проучим написването на странични тестови казуси за продуценти и потребители за Spring Cloud Contract чрез HTTP взаимодействие.

2. Производител - Сървърна страна

Отиваме да напише страна производител CDC, под формата на EvenOddController - което само показва дали на брой параметър е дори и странно:

@RestController public class EvenOddController { @GetMapping("/validate/prime-number") public String isNumberPrime(@RequestParam("number") Integer number) { return Integer.parseInt(number) % 2 == 0 ? "Even" : "Odd"; } }

2.1. Зависимости на Maven

За нашата страна на производителя ще ни е необходима зависимостта spring-star-starter-договор-верификатор :

 org.springframework.cloud spring-cloud-starter-contract-verifier 2.1.1.RELEASE test 

И ще трябва да конфигурираме spring-cloud-contract-maven-plugin с името на нашия основен тестов клас, което ще опишем в следващия раздел:

 org.springframework.cloud spring-cloud-contract-maven-plugin 2.1.1.RELEASE true   com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass   

2.2. Производителска странична настройка

Трябва да добавим основен клас в тестовия пакет, който зарежда нашия Spring контекст:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @DirtiesContext @AutoConfigureMessageVerifier public class BaseTestClass { @Autowired private EvenOddController evenOddController; @Before public void setup() { StandaloneMockMvcBuilder standaloneMockMvcBuilder = MockMvcBuilders.standaloneSetup(evenOddController); RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder); } }

В пакета / src / test / resources / договорите / ще добавим тестови заглушки , като този във файла shouldReturnEvenWhenRequestParamIsEven.groovy :

import org.springframework.cloud.contract.spec.Contract Contract.make { description "should return even when number input is even" request{ method GET() url("/validate/prime-number") { queryParameters { parameter("number", "2") } } } response { body("Even") status 200 } } 

Когато стартираме компилацията, плъгинът автоматично генерира тестов клас с име ContractVerifierTest, който разширява нашия BaseTestClass и го поставя в / target / generated-test-sources / contract / .

Имената на методите за тестване са получени от префикса „ валидиране_“, обединен с имената на нашите тестове на Groovy. За горния файл на Groovy генерираното име на метода ще бъде „validate_shouldReturnEvenWhenRequestParamIsEven“ .

Нека да разгледаме този автоматично генериран тест клас:

public class ContractVerifierTest extends BaseTestClass { @Test public void validate_shouldReturnEvenWhenRequestParamIsEven() throws Exception { // given: MockMvcRequestSpecification request = given(); // when: ResponseOptions response = given().spec(request) .queryParam("number","2") .get("/validate/prime-number"); // then: assertThat(response.statusCode()).isEqualTo(200); // and: String responseBody = response.getBody().asString(); assertThat(responseBody).isEqualTo("Even"); } 

Компилацията също ще добави буркана за заглушаване в нашето местно хранилище на Maven, така че да може да се използва от нашия потребител.

Stubs ще присъстват в изходната папка под stubs / mapping / .

3. Потребител - клиентска страна

Потребителската страна на нашия CDC ще консумира мъничета, генерирани от страна на производителя чрез HTTP взаимодействие, за да поддържа договора, така че всякакви промени от страна на производителя биха нарушили договора .

Ще добавим BasicMathController, който ще направи HTTP заявка, за да получи отговора от генерираните мъничета:

@RestController public class BasicMathController { @Autowired private RestTemplate restTemplate; @GetMapping("/calculate") public String checkOddAndEven(@RequestParam("number") Integer number) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("Content-Type", "application/json"); ResponseEntity responseEntity = restTemplate.exchange( "//localhost:8090/validate/prime-number?number=" + number, HttpMethod.GET, new HttpEntity(httpHeaders), String.class); return responseEntity.getBody(); } }

3.1. Зависимостите на Maven

За нашия потребител ще трябва да добавим зависимостите spring-cloud-contract-wiremock и spring-cloud-contract-stub-runner :

 org.springframework.cloud spring-cloud-contract-wiremock 2.1.1.RELEASE test   org.springframework.cloud spring-cloud-contract-stub-runner 2.1.1.RELEASE test  

3.2. Потребителска настройка

Сега е време да конфигурираме нашия stub runner, който ще информира потребителя ни за наличните заглушки в нашето местно хранилище Maven:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureJsonTesters @AutoConfigureStubRunner( stubsMode = StubRunnerProperties.StubsMode.LOCAL, ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090") public class BasicMathControllerIntegrationTest { @Autowired private MockMvc mockMvc; @Test public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/calculate?number=2") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("Even")); } }

Имайте предвид, че свойството ids на анотацията @AutoConfigureStubRunner определя:

  • com.baeldung.spring.cloud - идентификаторът на групата на нашия артефакт
  • spring-cloud-договор-производител - артефактният идентификатор на бурканчето на производителя
  • 8090 - портът, на който ще се изпълняват генерираните мъничета

4. Когато договорът е нарушен

Ако направим някакви промени от страна на производителя, които пряко въздействат върху договора, без да актуализираме потребителската страна, това може да доведе до провал на договора.

Да предположим например, че трябва да променим URI на заявката EvenOddController на / валидиране / промяна / първоначално число от нашата страна на производителя.

Ако не успеем да информираме потребителя си за тази промяна, потребителят все още ще изпрати заявката си до URI на / validate / prime-number и потребителските тестови случаи ще изхвърлят org.springframework.web.client.HttpClientErrorException: 404 Not Found .

5. Обобщение

Видяхме как Spring Cloud Contract може да ни помогне да поддържаме договори между потребител на услуга и производител, така че да можем да изтласкаме нов код, без да се притесняваме да нарушим договорите.

И както винаги, пълното изпълнение на този урок може да бъде намерено в GitHub.