1. Prerequisites

In order to use Spring Cloud Contract Verifier with WireMock, you must use either a Gradle or a Maven plugin.

If you want to use Spock in your projects, you must separately add the spock-core and spock-spring modules. See Spock’s documnetation for more information

2. Add Gradle Plugin with Dependencies

To add a Gradle plugin with dependencies, you can use code similar to the following:

Plugin DSL GA versions
// build.gradle
plugins {
  id "groovy"
  // this will work only for GA versions of Spring Cloud Contract
  id "org.springframework.cloud.contract" version "${GAVerifierVersion}"
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${GAVerifierVersion}"
    }
}

dependencies {
    testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}"
    // example with adding Spock core and Spock Spring
    testCompile "org.spockframework:spock-core:${spockVersion}"
    testCompile "org.spockframework:spock-spring:${spockVersion}"
    testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
Plugin DSL non GA versions
// settings.gradle
pluginManagement {
    plugins {
        id "org.springframework.cloud.contract" version "${verifierVersion}"
    }
    repositories {
        // to pick from local .m2
        mavenLocal()
        // for snapshots
        maven { url "https://repo.spring.io/snapshot" }
        // for milestones
        maven { url "https://repo.spring.io/milestone" }
        // for GA versions
        gradlePluginPortal()
    }
}

// build.gradle
plugins {
  id "groovy"
  id "org.springframework.cloud.contract"
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifierVersion}"
    }
}

dependencies {
    testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}"
    // example with adding Spock core and Spock Spring
    testCompile "org.spockframework:spock-core:${spockVersion}"
    testCompile "org.spockframework:spock-spring:${spockVersion}"
    testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
Legacy Plugin Application
// build.gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}"
        classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}"
        // here you can also pass additional dependencies such as Pact or Kotlin spec e.g.:
        // classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:${verifier_version}"
    }
}

apply plugin: 'groovy'
apply plugin: 'spring-cloud-contract'

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:${verifier_version}"
    }
}

dependencies {
    testCompile "org.codehaus.groovy:groovy-all:${groovyVersion}"
    // example with adding Spock core and Spock Spring
    testCompile "org.spockframework:spock-core:${spockVersion}"
    testCompile "org.spockframework:spock-spring:${spockVersion}"
    testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}

3. Gradle and Rest Assured 2.0

By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x you can add it to the plugins classpath, as the following listing shows:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springboot_version}"
        classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:${verifier_version}"
        classpath "com.jayway.restassured:rest-assured:2.5.0"
        classpath "com.jayway.restassured:spring-mock-mvc:2.5.0"
    }
}

depenendencies {
    // all dependencies
    // you can exclude rest-assured from spring-cloud-contract-verifier
    testCompile "com.jayway.restassured:rest-assured:2.5.0"
    testCompile "com.jayway.restassured:spring-mock-mvc:2.5.0"
}

That way, the plugin automatically sees that Rest Assured 2.x is present on the classpath and modifies the imports accordingly.

4. Snapshot Versions for Gradle

You can add the additional snapshot repository to your build.gradle to use snapshot versions, which are automatically uploaded after every successful build, as the following listing shows:

/*
 We need to use the [buildscript {}] section when we have to modify
 the classpath for the plugins. If that's not the case this section
 can be skipped.

 If you don't need to modify the classpath (e.g. add a Pact dependency),
 then you can just set the [pluginManagement {}] section in [settings.gradle] file.

 // settings.gradle
 pluginManagement {
    repositories {
        // for snapshots
        maven {url "https://repo.spring.io/snapshot"}
        // for milestones
        maven {url "https://repo.spring.io/milestone"}
        // for GA versions
        gradlePluginPortal()
    }
 }

 */
buildscript {
    repositories {
        mavenCentral()
        mavenLocal()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
        maven { url "https://repo.spring.io/release" }
    }
}

5. Add stubs

By default, Spring Cloud Contract Verifier looks for stubs in the src/test/resources/contracts directory.

The directory that contains stub definitions is treated as a class name, and each stub definition is treated as a single test. Spring Cloud Contract Verifier assumes that it contains at least one level of directories that are to be used as the test class name. If more than one level of nested directories is present, all except the last one is used as the package name. Consider the following structure:

src/test/resources/contracts/myservice/shouldCreateUser.groovy
src/test/resources/contracts/myservice/shouldReturnUser.groovy

Given the preceding structure, Spring Cloud Contract Verifier creates a test class named defaultBasePackage.MyService with two methods:

  • shouldCreateUser()

  • shouldReturnUser()

6. Running the Plugin

The plugin registers itself to be invoked before a check task. If you want it to be part of your build process, you need do nothing more. If you just want to generate tests, invoke the generateContractTests task.

7. Default Setup

The default Gradle Plugin setup creates the following Gradle part of the build (in pseudocode):

contracts {
    testFramework ='JUNIT'
    testMode = 'MockMvc'
    generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/contracts")
    generatedTestResourcesDir = project.file("${project.buildDir}/generated-test-resources/contracts")
    contractsDslDir = project.file("${project.rootDir}/src/test/resources/contracts")
    basePackageForTests = 'org.springframework.cloud.verifier.tests'
    stubsOutputDir = project.file("${project.buildDir}/stubs")
    sourceSet = null

    // the following properties are used when you want to provide where the JAR with contract lays
    contractDependency {
        stringNotation = ''
    }
    contractsPath = ''
    contractsWorkOffline = false
    contractRepository {
        cacheDownloadedContracts(true)
    }
}

tasks.create(type: Jar, name: 'verifierStubsJar', dependsOn: 'generateClientStubs') {
    baseName = project.name
    classifier = contracts.stubsSuffix
    from contractVerifier.stubsOutputDir
}

project.artifacts {
    archives task
}

tasks.create(type: Copy, name: 'copyContracts') {
    from contracts.contractsDslDir
    into contracts.stubsOutputDir
}

verifierStubsJar.dependsOn 'copyContracts'

publishing {
    publications {
        stubs(MavenPublication) {
            artifactId project.name
            artifact verifierStubsJar
        }
    }
}

8. Configuring the Plugin

To change the default configuration, you can add a contracts snippet to your Gradle configuration, as the following listing shows:

contracts {
    testMode = 'MockMvc'
    baseClassForTests = 'org.mycompany.tests'
    generatedTestSourcesDir = project.file('src/generatedContract')
}

9. Configuration Options

  • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, which is based on Spring’s MockMvc. It can also be changed to WebTestClient, JaxRsClient, or Explicit (for real HTTP calls).

  • imports: Creates an array with imports that should be included in the generated tests (for example, ['org.myorg.Matchers']). By default, it creates an empty array.

  • staticImports: Creates an array with static imports that should be included in generated tests(for example, ['org.myorg.Matchers.*']). By default, it creates an empty array.

  • basePackageForTests: Specifies the base package for all generated tests. If not set, the value is picked from the package of baseClassForTests and from packageWithBaseClasses. If neither of these values are set, the value is set to org.springframework.cloud.contract.verifier.tests.

  • baseClassForTests: Creates a base class for all generated tests. By default, if you use Spock classes, the class is spock.lang.Specification.

  • packageWithBaseClasses: Defines a package where all the base classes reside. This setting takes precedence over baseClassForTests.

  • baseClassMappings: Explicitly maps a contract package to a FQN of a base class. This setting takes precedence over packageWithBaseClasses and baseClassForTests.

  • ruleClassForTests: Specifies a rule that should be added to the generated test classes.

  • ignoredFiles: Uses an Antmatcher to allow defining stub files for which processing should be skipped. By default, it is an empty array.

  • contractsDslDir: Specifies the directory that contains contracts written by using the GroovyDSL. By default, its value is $rootDir/src/test/resources/contracts.

  • generatedTestSourcesDir: Specifies the test source directory where tests generated from the Groovy DSL should be placed. By default, its value is $buildDir/generated-test-sources/contracts.

  • generatedTestResourcesDir: Specifies the test resource directory where resources used by the tests generated from the Groovy DSL should be placed. By default, its value is $buildDir/generated-test-resources/contracts.

  • stubsOutputDir: Specifies the directory where the generated WireMock stubs from the Groovy DSL should be placed.

  • testFramework: Specifies the target test framework to be used. Currently, Spock, JUnit 4 (TestFramework.JUNIT), and JUnit 5 are supported, with JUnit 4 being the default framework.

  • contractsProperties: A map that contains properties to be passed to Spring Cloud Contract components. Those properties might be used by (for example) built-in or custom Stub Downloaders.

  • sourceSet: Source set where the contracts are stored. If not provided will assume test (e.g. project.sourceSets.test.java for JUnit or project.sourceSets.test.groovy for Spock).

You can use the following properties when you want to specify the location of the JAR that contains the contracts:

  • contractDependency: Specifies the Dependency that provides groupid:artifactid:version:classifier coordinates. You can use the contractDependency closure to set it up.

  • contractsPath: Specifies the path to the jar. If contract dependencies are downloaded, the path defaults to groupid/artifactid where groupid is slash separated. Otherwise, it scans contracts under the provided directory.

  • contractsMode: Specifies the mode for downloading contracts (whether the JAR is available offline, remotely, and so on).

  • deleteStubsAfterTest: If set to false, do not remove any downloaded contracts from temporary directories.

  • failOnNoContracts: When enabled, will throw an exception when no contracts were found. Defaults to true.

  • failOnInProgress: If set to true then if any contracts that are in progress are found, will break the build. On the producer side you need to be explicit about the fact that you have contracts in progress and take into consideration that you might be causing false positive test execution results on the consumer side.. Defaults to true.

There is also the contractRepository { …​ } closure that contains the following properties

  • repositoryUrl: the URL to the repository with contract definitions

  • username : Repository username

  • password : Repository password

  • proxyPort : the port of the proxy

  • proxyHost : the host of the proxy

  • cacheDownloadedContracts : If set to true then will cache the folder where non snapshot contract artifacts got downloaded. Defaults to true.

You can also turn on the following experimental features in the plugin:

  • convertToYaml: Converts all DSLs to the declarative YAML format. This can be extremely useful when you use external libraries in your Groovy DSLs. By turning this feature on (by setting it to true) you need not add the library dependency on the consumer side.

  • assertJsonSize: You can check the size of JSON arrays in the generated tests. This feature is disabled by default.

10. Single Base Class for All Tests

When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base specification for all generated acceptance tests. In this class, you need to point to an endpoint, which should be verified. The following example shows how to do so:

abstract class BaseMockMvcSpec extends Specification {

    def setup() {
        RestAssuredMockMvc.standaloneSetup(new PairIdController())
    }

    void isProperCorrelationId(Integer correlationId) {
        assert correlationId == 123456
    }

    void isEmpty(String value) {
        assert value == null
    }

}

If you use Explicit mode, you can use a base class to initialize the whole tested application, as you might see in regular integration tests. If you use the JAXRSCLIENT mode, this base class should also contain a protected WebTarget webTarget field. Right now, the only option to test the JAX-RS API is to start a web server.

11. Different Base Classes for Contracts

If your base classes differ between contracts, you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:

  • Follow a convention by providing the packageWithBaseClasses

  • Provide explicit mapping by using baseClassMappings

11.1. By Convention

The convention is such that if you have a contract in (for example) src/test/resources/contract/foo/bar/baz/ and set the value of the packageWithBaseClasses property to com.example.base, then Spring Cloud Contract Verifier assumes that there is a BarBazBase class under the com.example.base package. In other words, the system takes the last two parts of the package, if they exist, and forms a class with a Base suffix. This rule takes precedence over baseClassForTests. The following example shows how it works in the contracts closure:

packageWithBaseClasses = 'com.example.base'

11.2. By Mapping

You can manually map a regular expression of the contract’s package to the fully qualified name of the base class for the matched contract. You have to provide a list called baseClassMappings that consists of baseClassMapping objects that take a contractPackageRegex to baseClassFQN mapping. Consider the following example:

baseClassForTests = "com.example.FooBase"
baseClassMappings {
    baseClassMapping('.*/com/.*', 'com.example.ComBase')
    baseClassMapping('.*/bar/.*': 'com.example.BarBase')
}

Let’s assume that you have contracts in the following directories: - src/test/resources/contract/com/ - src/test/resources/contract/foo/

By providing baseClassForTests, we have a fallback in case mapping did not succeed. (You could also provide the packageWithBaseClasses as a fallback.) That way, the tests generated from src/test/resources/contract/com/ contracts extend the com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

12. Invoking Generated Tests

To ensure that the provider side is compliant with your defined contracts, you need to run the following command:

./gradlew generateContractTests test

13. Pushing Stubs to SCM

If you use the SCM repository to keep the contracts and stubs, you might want to automate the step of pushing stubs to the repository. To do that, you can call the pushStubsToScm task by running the following command:

$ ./gradlew pushStubsToScm

Under [scm-stub-downloader] you can find all possible configuration options that you can pass either through the contractsProperties field (for example, contracts { contractsProperties = [foo:"bar"] }), through the contractsProperties method (for example, contracts { contractsProperties([foo:"bar"]) }), or through a system property or an environment variable.

14. Spring Cloud Contract Verifier on the Consumer Side

In a consuming service, you need to configure the Spring Cloud Contract Verifier plugin in exactly the same way as in the case of a provider. If you do not want to use Stub Runner, you need to copy the contracts stored in src/test/resources/contracts and generate WireMock JSON stubs by using the following command:

./gradlew generateClientStubs
The stubsOutputDir option has to be set for stub generation to work.

When present, JSON stubs can be used in automated tests to consume a service. The following example shows how to do so:

@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
class LoanApplicationServiceSpec extends Specification {

 @ClassRule
 @Shared
 WireMockClassRule wireMockRule == new WireMockClassRule()

 @Autowired
 LoanApplicationService sut

 def 'should successfully apply for loan'() {
   given:
    LoanApplication application =
            new LoanApplication(client: new Client(clientPesel: '12345678901'), amount: 123.123)
   when:
    LoanApplicationResult loanApplication == sut.loanApplication(application)
   then:
    loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED
    loanApplication.rejectionReason == null
 }
}

In the preceding example, LoanApplication makes a call to the FraudDetection service. This request is handled by a WireMock server configured with stubs that were generated by Spring Cloud Contract Verifier.