此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 spring-cloud-contract 4.1.5spring-doc.cadn.net.cn

Gradle 项目

先决条件

要将 Spring Cloud Contract Verifier 与 WireMock 一起使用,必须使用 Gradle 或 Maven 插件。spring-doc.cadn.net.cn

如果你想在项目中使用 Spock,你必须单独添加spock-corespock-spring模块。查看 Spock's 文档了解更多信息。

添加具有依赖项的 Gradle 插件

要添加具有依赖项的 Gradle 插件,您可以使用类似于以下内容的代码:spring-doc.cadn.net.cn

插件 DSL GA 版本
// 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 {
	testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}"
	// example with adding Spock core and Spock Spring
	testImplementation "org.spockframework:spock-core:$\{spockVersion}"
	testImplementation "org.spockframework:spock-spring:$\{spockVersion}"
	testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
插件 DSL 非 GA 版本
// 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 {
	testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}"
	// example with adding Spock core and Spock Spring
	testImplementation "org.spockframework:spock-core:$\{spockVersion}"
	testImplementation "org.spockframework:spock-spring:$\{spockVersion}"
	testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
}
旧版插件应用程序
// 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 Kotlin spec e.g.:
        // classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:$\{verifier_version}"
	}
}

apply plugin: 'groovy'
apply plugin: 'org.springframework.cloud.contract'

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

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

Gradle 和 Rest Assured 2.0

默认情况下,Rest Assured 3.x 将添加到 Classpath 中。但是,要使用 Rest Assured 2.x, 您可以添加它,如下面的清单所示:spring-doc.cadn.net.cn

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}"
	}
}

dependencies {
    // 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"
}

这样,插件会自动看到 Rest Assured 2.x 存在于 Classpath 中 并相应地修改导入。spring-doc.cadn.net.cn

Gradle 的快照版本

您可以将其他快照存储库添加到settings.gradle要使用快照版本, 这些 API 会在每次成功构建后自动上传。spring-doc.cadn.net.cn

添加存根

默认情况下, Spring Cloud Contract Verifier 在src/contractTest/resources/contracts目录。出于过渡目的,插件 也会在src/test/resources/contracts,但是,此目录 从 Spring Cloud Contract 3.0.0 开始已弃用。spring-doc.cadn.net.cn

还应注意,使用这个新的 Gradle 源代码集,您还应该迁移 合约中使用的任何基类都会测试为src/contractTest/{language}哪里{language}应根据您的目的需要替换为 Java 或 Groovy。spring-doc.cadn.net.cn

包含 stub 定义的目录被视为类名,每个 stub 定义被视为单个测试。Spring Cloud Contract Verifier 假定它 包含至少一个级别要用作测试类名的目录。 如果存在多个级别的嵌套目录,则使用除最后一个目录之外的所有目录 作为软件包名称。请考虑以下结构:spring-doc.cadn.net.cn

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

给定前面的结构, Spring Cloud Contract Verifier 创建一个名为defaultBasePackage.MyService有两种方法:spring-doc.cadn.net.cn

运行插件

插件将自身注册为在check任务。如果你希望它是 作为构建过程的一部分,您无需执行更多作。如果只想生成 测试中,调用generateContractTests任务。spring-doc.cadn.net.cn

默认设置

默认的 Gradle 插件设置会创建构建的以下 Gradle 部分(在 伪代码):spring-doc.cadn.net.cn

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

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

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

verifierStubsJar.dependsOn copyContracts

配置插件

要更改默认配置,您可以添加contractssnippet 添加到您的 Gradle 配置,如下面的清单所示:spring-doc.cadn.net.cn

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

要从远程源下载合同,您可以根据需要使用以下代码段:spring-doc.cadn.net.cn

contracts {
    // If your contracts exist in a JAR archive published to a Maven repository
    contractDependency {
        stringNotation = ''
        // OR
        groupId = ''
        artifactId = ''
        version = ''
        classifier = ''
    }

    // If your contracts exist in a Git SCM repository
    contractRepository {
        repositoryUrl = ''
        // username = ''
        // password = ''
    }

    // controls the nested location to find the contracts in either the JAR or Git SCM source
    contractsPath = ''
}

由于我们使用的是 Gradle 的 Jar 打包任务,因此您可能希望利用多个选项和功能来进一步扩展由verifierStubsJar.为此,您将使用 Gradle 直接提供的本机机制来自定义现有任务,如下所示:spring-doc.cadn.net.cn

为了示例,我们希望添加一个git.properties文件添加到verifierStubsJar.
verifierStubsJar {
    from("$\{buildDir}/resources/main/") {
        include("git.properties")
    }
}

还应注意,从 3.0.0 开始,默认发布已被禁用。因此,这意味着您可以创建任何命名的 jar 并发布它,就像您通常通过 Gradle 配置选项所做的那样。这意味着您可以按照自己的方式构建自定义的 jar 文件,并发布该文件,以便对 jar 的布局和内容进行绝对的完全控制。spring-doc.cadn.net.cn

配置选项

  • testMode:定义验收测试的模式。默认情况下,模式为 MockMvc, 它基于 Spring 的 MockMvc。它也可以更改为 WebTestClient、JaxRsClient 或 显式(用于实际 HTTP 调用)。spring-doc.cadn.net.cn

  • imports:创建一个包含应包含在生成的测试中的导入的数组 (例如,['org.myorg.Matchers']).默认情况下,它会创建一个空数组。spring-doc.cadn.net.cn

  • staticImports:创建一个包含应包含在 生成的测试(例如['org.myorg.Matchers.*']).默认情况下,它会创建一个空的 数组。spring-doc.cadn.net.cn

  • basePackageForTests:指定所有生成的测试的基础包。如果未设置,则 该值是从baseClassForTests和 从packageWithBaseClasses. 如果这两个值均未设置,则该值将设置为org.springframework.cloud.contract.verifier.tests.spring-doc.cadn.net.cn

  • baseClassForTests:为所有生成的测试创建一个基类。默认情况下,如果你 使用 Spock 类,则 class 为spock.lang.Specification.spring-doc.cadn.net.cn

  • packageWithBaseClasses:定义所有基类所在的包。这 设置优先于baseClassForTests.spring-doc.cadn.net.cn

  • baseClassMappings:将协定包显式映射到基类的 FQN。这 设置优先于packageWithBaseClassesbaseClassForTests.spring-doc.cadn.net.cn

  • ignoredFiles:使用Antmatcher允许定义要处理的存根文件 应该跳过。默认情况下,它是一个空数组。spring-doc.cadn.net.cn

  • contractsDslDir:指定包含使用 GroovyDSL 的默认情况下,其值为$projectDir/src/contractTest/resources/contracts.spring-doc.cadn.net.cn

  • generatedTestSourcesDir:指定生成测试的测试源目录 应该放置 Groovy DSL。(已弃用)spring-doc.cadn.net.cn

  • generatedTestJavaSourcesDir:指定测试源目录,从 Groovy DSL 生成的 Java/JUnit 测试应放置在其中。默认情况下,它的值为$buildDir/generated-tes-sources/contractTest/java.spring-doc.cadn.net.cn

  • generatedTestGroovySourcesDir:指定测试源目录,应将从 Groovy DSL 生成的 Groovy/Spock 测试放置在该目录下。默认情况下,它的值为$buildDir/generated-test-sources/contractTest/groovy.spring-doc.cadn.net.cn

  • generatedTestResourcesDir:指定测试使用的资源的测试资源目录,其中生成了测试 应该放置 Groovy DSL。默认情况下,其值为$buildDir/generated-test-resources/contractTest.spring-doc.cadn.net.cn

  • stubsOutputDir:指定生成的 WireMock 存根的目录 应该放置 Groovy DSL。spring-doc.cadn.net.cn

  • testFramework:指定要使用的目标测试框架。目前,Spock、JUnit 4 (TestFramework.JUNIT) 和 支持 JUnit 5,其中 JUnit 4 是默认框架。spring-doc.cadn.net.cn

  • contractsProperties:包含要传递给 Spring Cloud Contract 的属性的 map 组件。这些属性可能由(例如)内置或自定义 Stub Downloader 使用。spring-doc.cadn.net.cn

  • sourceSet:存储合同的源集。如果未提供,将假定contractTest(例如,project.sourceSets.contractTest.javafor JUnit 或project.sourceSets.contractTest.groovy为 Spock)。spring-doc.cadn.net.cn

当您想要指定 JAR 的位置时,可以使用以下属性 ,其中包含 Contracts:spring-doc.cadn.net.cn

  • contractDependency:指定提供groupid:artifactid:version:classifier坐标。您可以使用contractDependencyclosure 进行设置。spring-doc.cadn.net.cn

  • contractsPath:指定 jar 的路径。如果合约依赖项为 downloaded,则路径默认为groupid/artifactid哪里groupid是斜杠 分开。否则,它会扫描提供的目录下的 Contract。spring-doc.cadn.net.cn

  • contractsMode:指定下载合约的方式(无论 JAR 可脱机、远程使用等)。spring-doc.cadn.net.cn

  • deleteStubsAfterTest:如果设置为false,不会删除任何已下载的 来自临时目录的 Contract。spring-doc.cadn.net.cn

  • failOnNoContracts:启用后,如果未找到 Contract,将引发异常。默认为true.spring-doc.cadn.net.cn

  • failOnInProgress:如果设置为true,然后,如果找到任何正在进行的合同,它们就会中断构建。在生产者方面,您需要明确说明您有正在进行的合同这一事实,并考虑到您可能会在消费者方面导致误报测试结果。默认为true.spring-doc.cadn.net.cn

还有contractRepository { …​ }包含以下属性的 closurespring-doc.cadn.net.cn

您还可以在插件中打开以下实验性功能:spring-doc.cadn.net.cn

  • convertToYaml:将所有 DSL 转换为声明式 YAML 格式。这可能是非常 当您在 Groovy DSL 中使用外部库时很有用。通过启用此功能 (通过将其设置为true),则无需在使用者端添加库依赖项。spring-doc.cadn.net.cn

  • assertJsonSize:您可以在生成的测试中检查 JSON 数组的大小。这 功能默认处于禁用状态。spring-doc.cadn.net.cn

所有测试的单个基类

在 MockMvc(默认)中使用 Spring Cloud Contract Verifier 时,你需要创建一个 base 规范。在此类中,您需要指向一个 endpoint,该端点应进行验证。以下示例显示了如何执行此作:spring-doc.cadn.net.cn

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
	}

}

如果您使用Explicitmode 中,您可以使用基类来初始化整个测试应用程序 正如您在常规集成测试中可能看到的那样。如果您使用JAXRSCLIENTmode 中,此 基类还应包含一个protected WebTarget webTarget田。现在, 测试 JAX-RS API 的唯一选项是启动 Web 服务器。spring-doc.cadn.net.cn

Contract 的不同基类

如果您的基类在 Contract 之间不同,则可以告诉 Spring Cloud Contract plugin 哪个类应该由自动生成的测试进行扩展。您有两个选项:spring-doc.cadn.net.cn

按约定

约定是这样的,如果您在 (例如)src/contractTest/resources/contract/foo/bar/baz/并设置packageWithBaseClassesproperty 设置为com.example.base,然后是 Spring Cloud Contract 验证程序假定存在BarBazBasecom.example.base包。 换句话说,系统采用包的最后两部分(如果存在),并且 形成一个类,其中包含Base后缀。此规则优先于baseClassForTests.spring-doc.cadn.net.cn

按映射

您可以手动将 Contract 包的正则表达式映射到完全限定的 匹配合约的基类名称。您必须提供一个名为baseClassMappings包括baseClassMapping采用contractPackageRegexbaseClassFQN映射。spring-doc.cadn.net.cn

假设您在以下目录中有 Contract:spring-doc.cadn.net.cn

通过提供baseClassForTests,如果映射未成功,我们有一个回退。 (您还可以提供packageWithBaseClasses作为后备。这样,测试 生成自src/contractTest/resources/contract/com/合约扩展了com.example.ComBase,而其余测试扩展com.example.FooBase.spring-doc.cadn.net.cn

调用生成的测试

要确保 provider 端符合您定义的 Contract ,您需要运行 以下命令:spring-doc.cadn.net.cn

./gradlew contractTest

将桩模块发布到构件存储库

如果您使用二进制构件存储库来保留存根,则 您需要配置 Gradle 的发布部分,以便 包括verifierStubsJar.为此,您可以使用 示例配置如下:spring-doc.cadn.net.cn

apply plugin: 'maven-publish'

publishing {
    publications {
        maven(MavenPublication) {
            // other configuration

            artifact verifierStubsJar
        }
    }
}

从 3.0.0 开始,内部存根发布已被弃用 和 Disabled 的 Enabled 。建议包含verifierStubsJar替换为您自己的出版物之一。spring-doc.cadn.net.cn

将存根推送到 SCM

如果您使用 SCM 存储库来保留合同和 stubs 中,您可能希望自动执行将 stub 推送到 存储库。为此,您可以调用pushStubsToScmtask 来执行以下命令:spring-doc.cadn.net.cn

$ ./gradlew pushStubsToScm

Using the SCM Stub Downloader 下,您可以找到所有可能的 配置选项,您可以通过 这contractsProperties字段(例如contracts { contractsProperties = [foo:"bar"] }), 通过contractsProperties方法(例如contracts { contractsProperties([foo:"bar"]) }), 或通过系统属性或环境变量。spring-doc.cadn.net.cn

Consumer 端的 Spring Cloud Contract Verifier

在消费服务中,您需要配置 Spring Cloud Contract Verifier 插件 与提供商的情况完全相同。如果您不想使用 Stub Runner,则 您需要复制存储在src/contractTest/resources/contracts并生成 使用以下命令对 WireMock JSON 存根进行作:spring-doc.cadn.net.cn

./gradlew generateClientStubs
stubsOutputDir选项,存根生成才能正常工作。

如果存在,您可以在自动测试中使用 JSON 存根来使用服务。这 以下示例显示了如何执行此作:spring-doc.cadn.net.cn

@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
 }
}

在前面的示例中,LoanApplication调用FraudDetection服务。 此请求由 WireMock 服务器处理,该服务器配置了由 Spring Cloud Contract Verifier 中。spring-doc.cadn.net.cn