Spring Cloud Contract
Last Updated :
29 Apr, 2024
Spring Cloud Contract is a framework for writing Consumer Driven Contracts (CDC) in Spring applications. It enables teams to define contracts between microservices, ensuring proper communication. Spring Cloud Contract allows developers to create and manage contracts for RESTful APIs, ensuring consistency and reliability across distributed systems. Automating contract testing helps improve efficiency and reduce integration issues between projects.
Spring Cloud Contract is an umbrella service that includes tools to help customers incorporate customer-friendly contracting options. Currently, the Spring Cloud contract contains the Spring Cloud Contract Verifier Project.
Implementation of Spring Cloud Contract
Step 1: Add Dependencies
We may include the Spring Cloud Contract Verifier dependency and plugin in our build file, as shown in the following example:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-contract-verifier</artifactId>
<scope>test</scope>
</dependency>
Step 2: Specify the Base Test Class
The following example from pom.xml demonstrates how to provide the basic test class.
XML
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>3.1.2.RELEASE</version>
<extensions>true</extensions>
<configuration>
<baseClassForTests>com.example.contractTest.BaseTestClass</baseClassForTests>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Step 3: Include a Basic Class in the Package
This test class creates a mock environment and a Spring context for testing a Spring Boot application. It sets up the required configuration for the tests to function properly and initializes a controller for testing.
Java
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder;
import io.restassured.module.mockmvc.RestAssuredMockMvc;
import com.example.controllers.EvenOddController;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@DirtiesContext
@AutoConfigureMessageVerifier
public class YourNewTestClass {
@Autowired
private EvenOddController evenOddController;
@Before
public void setup() {
StandaloneMockMvcBuilder standaloneMockMvcBuilder
= MockMvcBuilders.standaloneSetup(evenOddController);
RestAssuredMockMvc.standaloneSetup(standaloneMockMvcBuilder);
}
}
- The @SpringBootTest annotation is utilized to define the loading and configuration parameters for the Spring ApplicationContext. Here, it offers a simulated web environment along with loading the entire application context.
- @DirtiesContext annotation suggests that the test’s Spring ApplicationContext has to be closed and deleted following test execution since it is unclean.
Step 4: Configure the Consumer – Client Side
To preserve the contract, the consumer side of our CDC will consume stubs created by the producer side via HTTP interaction; hence, any modifications on the producer side will break the contract.
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class NewMathController {
@Autowired
private RestTemplate newRestTemplate;
@GetMapping("/calculate")
public String checkOddAndEven(@RequestParam("number") Integer number) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Type", "application/json");
ResponseEntity<String> responseEntity = newRestTemplate.exchange(
"http://localhost:8090/validate/prime-number?number=" + number,
HttpMethod.GET,
new HttpEntity<>(httpHeaders),
String.class);
return responseEntity.getBody();
}
}
Step 5: Available stubs information
For microservices-based architectures to be reliable and correct, integration testing is essential. It is critical to verify that services in these distributed systems communicate appropriately and follow established contracts. Next set up stub runner, which will notify consumers about the available stubs in local Maven repository:
Java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
@AutoConfigureJsonTesters
@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.LOCAL,
ids = "org.geeksforgeeks.spring.cloud:spring-cloud-contract-producer:+:stubs:8090")
public class NewMathControllerIntegrationTest {
@Autowired
private MockMvc newMockMvc;
@Test
public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven()
throws Exception {
newMockMvc.perform(MockMvcRequestBuilders.get("/calculate?number=2")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string("Even"));
}
}
- @SpringBootTest indicates how to load and set up the Spring ApplicationContext using this annotation. Here, it loads the entire application context and offers a test-ready fake web environment.
- @AutoConfigureStubRunner sets up a Stub Runner automatically to use stubs from a local or remote repository. It is set up to retrieve stubs from a local repository in this instance.
- newMockMvc.execute() is used where you can begin a simulated HTTP request. It is employed to provide a number=2 query parameter along with an HTTP GET request to the /calculate endpoint.
Share your thoughts in the comments
Please Login to comment...