MVN

au.com.dius : pact-jvm-provider-spring

Maven & Gradle

Apr 18, 2020
1k stars

pact-jvm-provider-spring · # Pact Spring/JUnit runner ## Overview Library provides ability to play contract tests against a provider using Spring & JUnit. This library is based on and references the JUnit package, so see the [Pact JUnit 4](../pact-jvm-provider-junit) or [Pact JUnit 5](../pact-jvm-provider-junit5) providers for more details regarding configuration using JUnit. Supports: - Standard ways to load pacts from folders and broker - Easy way to change assertion strategy - Spring Test MockMVC Controllers and ControllerAdvice using MockMvc standalone setup. - MockMvc debugger output - Multiple @State runs to test a particular Provider State multiple times - **au.com.dius.pact.provider.junit.State** custom annotation - before each interaction that requires a state change, all methods annotated by `@State` with appropriate the state listed will be invoked. **NOTE:** For publishing provider verification results to a pact broker, make sure the Java system property `pact.provider.version` is set with the version of your provider. ## Example of MockMvc test ```java @RunWith(RestPactRunner.class) // Custom pact runner, child of PactRunner which runs only REST tests @Provider("myAwesomeService") // Set up name of tested provider @PactFolder("pacts") // Point where to find pacts (See also section Pacts source in documentation) public class ContractTest { //Create an instance of your controller. We cannot autowire this as we're not using (and don't want to use) a Spring test runner. @InjectMocks private AwesomeController awesomeController = new AwesomeController(); //Mock your service logic class. We'll use this to create scenarios for respective provider states. @Mock private AwesomeBusinessLogic awesomeBusinessLogic; //Create an instance of your controller advice (if you have one). This will be passed to the MockMvcTarget constructor to be wired up with MockMvc. @InjectMocks private AwesomeControllerAdvice awesomeControllerAdvice = new AwesomeControllerAdvice(); //Create a new instance of the MockMvcTarget and annotate it as the TestTarget for PactRunner @TestTarget public final MockMvcTarget target = new MockMvcTarget(); @Before //Method will be run before each test of interaction public void before() { //initialize your mocks using your mocking framework MockitoAnnotations.initMocks(this); //configure the MockMvcTarget with your controller and controller advice target.setControllers(awesomeController); target.setControllerAdvice(awesomeControllerAdvice); } @State("default", "no-data") // Method will be run before testing interactions that require "default" or "no-data" state public void toDefaultState() { target.setRunTimes(3); //let's loop through this state a few times for a 3 data variants when(awesomeBusinessLogic.getById(any(UUID.class))) .thenReturn(myTestHelper.generateRandomReturnData(UUID.randomUUID(), ExampleEnum.ONE)) .thenReturn(myTestHelper.generateRandomReturnData(UUID.randomUUID(), ExampleEnum.TWO)) .thenReturn(myTestHelper.generateRandomReturnData(UUID.randomUUID(), ExampleEnum.THREE)); } @State("error-case") public void SingleUploadExistsState_Success() { target.setRunTimes(1); //tell the runner to only loop one time for this state //you might want to throw exceptions to be picked off by your controller advice when(awesomeBusinessLogic.getById(any(UUID.class))) .then(i -> { throw new NotCoolException(i.getArgumentAt(0, UUID.class).toString()); }); } } ``` ## Using Spring runners You can use `SpringRestPactRunner` or `SpringMessagePactRunner` instead of the default Pact runner to use the Spring test annotations. This will allow you to inject or mock spring beans. `SpringRestPactRunner` is for restful webapps and `SpringMessagePactRunner` is for async message tests. For example: ```java @RunWith(SpringRestPactRunner.class) @Provider("pricing") @PactBroker(protocol = "https", host = "${pactBrokerHost}", port = "443", authentication = @PactBrokerAuth(username = "${pactBrokerUser}", password = "${pactBrokerPassword}")) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class PricingServiceProviderPactTest { @MockBean private ProductClient productClient; // This will replace the bean with a mock in the application context @TestTarget @SuppressWarnings(value = "VisibilityModifier") public final Target target = new HttpTarget(8091); @State("Product X010000021 exists") public void setupProductX010000021() throws IOException { reset(productClient); ProductBuilder product = new ProductBuilder() .withProductCode("X010000021"); when(productClient.fetch((Set<String>) argThat(contains("X010000021")), any())).thenReturn(product); } @State("the product code X00001 can be priced") public void theProductCodeX00001CanBePriced() throws IOException { reset(productClient); ProductBuilder product = new ProductBuilder() .withProductCode("X00001"); when(productClient.find((Set<String>) argThat(contains("X00001")), any())).thenReturn(product); } } ``` ### Using Spring Context Properties The SpringRestPactRunner will look up any annotation expressions (like `${pactBrokerHost}`) above) from the Spring context. For Springboot, this will allow you to define the properties in the application test properties. For instance, if you create the following `application.yml` in the test resources: ```yaml pactbroker: host: "your.broker.local" port: "443" protocol: "https" auth: username: "<your broker username>" password: "<your broker password>" ``` Then you can use the defaults on the `@PactBroker` annotation. ```java @RunWith(SpringRestPactRunner.class) @Provider("My Service") @PactBroker( authentication = @PactBrokerAuth(username = "${pactbroker.auth.username}", password = "${pactbroker.auth.password}") ) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class PactVerificationTest { ``` ### Using a random port with a Springboot test If you use a random port in a springboot test (by setting `SpringBootTest.WebEnvironment.RANDOM_PORT`), you need to set it to the `TestTarget`. How this works is different for JUnit4 and JUnit5. #### JUnit4 You can use the `SpringBootHttpTarget` which will get the application port from the spring application context. For example: ```java @RunWith(SpringRestPactRunner.class) @Provider("My Service") @PactBroker @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class PactVerificationTest { @TestTarget public final Target target = new SpringBootHttpTarget(); } ``` #### JUnit5 You actually don't need to dependend on `pact-jvm-provider-spring` for this. It's sufficient to depend on `pact-jvm-provider-junit5`. You can set the port to the `HttpTestTarget` object in the before method. ```java @Provider("My Service") @PactBroker @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class PactVerificationTest { @LocalServerPort private int port; @BeforeEach void before(PactVerificationContext context) { context.setTarget(new HttpTestTarget("localhost", port)); } } ```

<dependency>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-provider-spring</artifactId>
    <version>4.0.10</version>
</dependency>
Copy
pom.xml
Table Of Contents

Latest Version

Choose a version of au.com.dius : pact-jvm-provider-spring to add to Maven or Gradle - Latest Versions:

  • Latest Stable: 4.0.10
  • Latest Beta: 4.0.0-beta.6

All Versions

Choose a version of au.com.dius : pact-jvm-provider-spring to add to Maven or Gradle - All Versions:

Version Vulnerabilities Updated
4.0.x
pact-jvm-provider-spring-4.0.10
pact-jvm-provider-spring-4.0.9
pact-jvm-provider-spring-4.0.8
pact-jvm-provider-spring-4.0.7
pact-jvm-provider-spring-4.0.6
pact-jvm-provider-spring-4.0.5
pact-jvm-provider-spring-4.0.4
pact-jvm-provider-spring-4.0.3
pact-jvm-provider-spring-4.0.2
pact-jvm-provider-spring-4.0.1
pact-jvm-provider-spring-4.0.0
pact-jvm-provider-spring-4.0.0-beta.6
pact-jvm-provider-spring-4.0.0-beta.5
pact-jvm-provider-spring-4.0.0-beta.4
pact-jvm-provider-spring-4.0.0-beta.3
pact-jvm-provider-spring-4.0.0-beta.2
pact-jvm-provider-spring-4.0.0-beta.1

How to add a dependency to Maven

Add the following au.com.dius : pact-jvm-provider-spring maven dependency to the pom.xml file with your favorite IDE (IntelliJ / Eclipse / Netbeans):

<dependency>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-provider-spring</artifactId>
    <version>4.0.10</version>
</dependency>

How to add a dependency to Gradle

Gradle Groovy DSL: Add the following au.com.dius : pact-jvm-provider-spring gradle dependency to your build.gradle file:

implementation 'au.com.dius:pact-jvm-provider-spring:4.0.10'

Gradle Kotlin DSL: Add the following au.com.dius : pact-jvm-provider-spring gradle kotlin dependency to your build.gradle.kts file:

implementation("au.com.dius:pact-jvm-provider-spring:4.0.10")

How to add a dependency to SBT Scala

SBT Scala: Add the following au.com.dius : pact-jvm-provider-spring sbt scala dependency to your build.sbt file:

libraryDependencies += "au.com.dius" % "pact-jvm-provider-spring" % "4.0.10"

Advertisement

Dependencies from Group

Apr 29, 2020
31 usages
1k stars
Nov 04, 2018
27 usages
1k stars
Nov 04, 2018
18 usages
1k stars
Apr 29, 2020
13 usages
1k stars
Apr 29, 2020
12 usages
1k stars

Discover Dependencies

Apr 18, 2020
9 usages
1k stars
orm
Apr 06, 2019
3 usages
0 stars
Apr 03, 2023
2 usages
4.8k stars
Aug 23, 2023
8 usages
20 stars
Aug 23, 2023
2 usages
20 stars
Aug 23, 2023
4 usages
20 stars
Jul 14, 2023
943 stars
Jan 24, 2023
270 stars
Feb 21, 2020
1 usages
May 22, 2019
44 stars