Gradle项目

前提条件

要使用 Spring Cloud 合同验证器配合 WireMock,您必须使用 Gradle 或 Maven 插件。spring-doc.cadn.net.cn

如果你想在项目中使用Spock,必须单独添加斯波克核心斯波克·斯普林模块。参见斯波克的 更多信息请见相关文献

添加带有依赖关系的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'
}
非GA版本的插件DSL
// 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与安息2.0

默认情况下,Rest Assured 3.x 会被添加到类路径中。不过,使用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 存在于类路径上 并相应地修改导入。spring-doc.cadn.net.cn

Gradle 快照版本

你可以将额外的快照仓库添加到你的settings.gradle使用快照版本, 每次成功构建后会自动上传。spring-doc.cadn.net.cn

添加小作品

默认情况下,Spring Cloud 合同验证器会在src/contractTest/资源/合同目录。为了过渡目的,插件 我也会寻找合同SRC/测试/资源/合同然而,这个目录 自 Spring Cloud Contract 3.0.0 起已被弃用。spring-doc.cadn.net.cn

还需要注意的是,使用这个新的 Gradle 源集,你也应该进行迁移 你合同中使用的任何基类都会测试src/contractTest/{language}哪里{语言}根据你的需求,应该用 Java 或 Groovy 替代。spring-doc.cadn.net.cn

包含存根定义的目录被视为类名,每个存根 定义被视为单一测试。Spring Cloud 合同验证器假设它 包含至少一层将用作测试类名称的目录。 如果存在多个层级的嵌套目录,则除最后一个外,所有层级都被使用。 作为包裹名称。考虑以下结构: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

运行插件

该插件会在检查任务。如果你愿意 作为构建过程的一部分,你无需做更多事情。如果你只想生成 测试,调用生成ContractTesting任务。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

插件配置

要更改默认配置,可以添加一个合同你的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的罐子打包任务,你可以利用多种选项和功能进一步扩展由验证者StubsJar.为此,你可以直接使用Gradle提供的原生机制来自定义现有任务,比如:spring-doc.cadn.net.cn

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

还应注意,从 3.0.0 版本起,默认发布已被禁用。因此,你可以创建任何命名的jar,并像通常通过Gradle配置选项那样发布。这意味着你可以根据自己的喜好构建一个 jar 文件,并发布它,完全掌控 jar 的布局和内容。spring-doc.cadn.net.cn

配置选项

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

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

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

  • basePackageForTests: 指定所有生成测试的基础包。如果没有设置, 取值从包中选取baseClassForTests以及来自packageWithBaseClasses. 如果这两个值都未被设置,则该值设为org.springframework.cloud.contract.verifier.tests.spring-doc.cadn.net.cn

  • baseClassForTests为所有生成的测试创建基类。默认情况下,如果你 使用斯波克类,该类为spock.lang.规范.spring-doc.cadn.net.cn

  • packageWithBaseClasses定义了一个包,所有基类都存在。这 环境优先于环境baseClassForTests.spring-doc.cadn.net.cn

  • baseClassMappings: 明确地将合同包映射到基类的 FQN。这 环境优先于环境packageWithBaseClassesbaseClassForTests.spring-doc.cadn.net.cn

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

  • contractsDslDir: 指定包含使用以下 GroovyDSL。默认情况下,其值为$projectDir/src/contractTest/资源/合同.spring-doc.cadn.net.cn

  • 生成测试源Dir: 指定测试源目录,生成测试 应该从Groovy DSL中放置。(被淘汰)spring-doc.cadn.net.cn

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

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

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

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

  • testFramework: 指定将使用的目标测试框架。目前,斯波克,JUnit 4(TestFramework.JUNIT) 支持JUnit 5,JUnit 4为默认框架。spring-doc.cadn.net.cn

  • 合同财产:包含要传递给春云合约的属性的映射 组件。这些属性可能被(例如)内置或自定义的存根下载器使用。spring-doc.cadn.net.cn

  • sourceSet: 存储合同的源集。如果未提供,将假设合同测试(例如,project.sourceSets.contractTest.java对于JUnit或项目.sourceSets.contractTest.groovy斯波克)。spring-doc.cadn.net.cn

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

  • 合同依赖关系: 指定提供 的依赖关系GroupID:ArtifactID:version:classifier坐标。你可以使用合同依赖关系为了建立关系而有个了结。spring-doc.cadn.net.cn

  • 合同路径: 指定通往罐子的路径。如果合同依赖关系是 下载后,路径默认为Groupid/Artifactid哪里群体是同人 分开。否则,它会在提供的目录下扫描合同。spring-doc.cadn.net.cn

  • 合同模式: 指定下载合同的模式(如果 JAR可以离线、远程使用等等。spring-doc.cadn.net.cn

  • deleteStubsAfterTest(删除小截图)AfterTest:如果设置为false, 不会删除任何已下载的 临时目录中的合同。spring-doc.cadn.net.cn

  • failOnNoContracts启用时,当未找到合同时,将抛出异常。默认true.spring-doc.cadn.net.cn

  • 失败进行:如果设置为true然后,如果发现任何正在进行中的合同,它们就会破坏构建。在生产方方面,你需要明确说明你有合同正在进行中,并考虑到这可能导致消费者端出现假阳性检测结果。默认true.spring-doc.cadn.net.cn

还有contractRepository { ... }包含以下性质的闭包spring-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 合约验证器时,你需要创建一个基础 所有生成验收测试的规范。在这门课中,你需要指向一个 端点,应该经过验证。以下示例展示了如何实现: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
	}

}

如果你使用,明确模式,你可以用基类初始化整个测试应用, 正如你在普通积分测试中看到的那样。如果你使用了JAXRS客户端模式,这个 基类还应包含受保护的WebTarget webTarget田。目前, 测试JAX-RS API的唯一选择是启动一个网页服务器。spring-doc.cadn.net.cn

不同的契约基类

如果你的基础类不同契约不同,你可以判断 Spring Cloud 合约 插件,哪个类应该被自动生成的测试扩展。你有两个选择:spring-doc.cadn.net.cn

按惯例

该惯例是,如果你在(例如)中有一个合同src/contractTest/resources/contract/foo/bar/baz/并设置 的值packageWithBaseClasses属性到com.example.base然后是春云合约 验证器假设存在BarBazBasecom.example.base包。 换句话说,系统会取包的最后两个部分(如果它们存在的话)和 构成一个类,满足基础后缀。此规则优先于此规则baseClassForTests.spring-doc.cadn.net.cn

按制图方式

你可以手动将合同包的正则表达式映射到完全合格的 匹配合同的基础类名称。你必须提供一份叫做baseClassMappingsbaseClassMapping具有contractPackageRegexbaseClassFQN映射。spring-doc.cadn.net.cn

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

通过提供baseClassForTests,如果映射失败,我们有一个备选方案。 (你也可以提供packageWithBaseClasses作为备选。)这样,测试 生成于src/contractTest/resources/contract/com/合同扩展了com.example.ComBase,而其他测试则扩展com.example.FooBase.spring-doc.cadn.net.cn

调用生成测试

为了确保提供者端符合你定义的合同,你需要运行 以下命令:spring-doc.cadn.net.cn

./gradlew contractTest

向文物仓库发布小作品

如果你使用二进制工件仓库来保存存根, 你需要配置 Gradle 的发布部分 包括验证者StubsJar.为此,你可以使用 以下是示例配置:spring-doc.cadn.net.cn

apply plugin: 'maven-publish'

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

            artifact verifierStubsJar
        }
    }
}

自3.0.0版本起,内部小作品发布已被弃用 并且默认为禁用。建议包括验证者StubsJar通过你自己的出版物。spring-doc.cadn.net.cn

向SCM推送小作品

如果你用SCM仓库来保存合同和 存根,你可能想自动化推送存根的步骤 仓库。为此,你可以调用pushStubsToScm通过执行以下命令来完成任务:spring-doc.cadn.net.cn

$ ./gradlew pushStubsToScm

“使用SCM存根下载器”中,你可以找到所有可能的资源 你可以通过这些配置选项 这合同财产域(例如,contracts { contractsProperties = [foo:“bar”] }), 通过合同财产方法(例如,contracts { contractsProperties([foo:“bar”]) }), 或者通过系统属性或环境变量。spring-doc.cadn.net.cn

Spring Cloud 合同验证器在消费者端

在消费型服务中,你需要配置 Spring Cloud Contract Verifier 插件 与服务提供者的情况完全相同。如果你不想用Stub Runner, 你需要复制存储在src/contractTest/资源/合同生成 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
 }
}

在上述例子中,贷款申请拨打电话给欺诈检测服务。 该请求由配置为 stub 的 WireMock 服务器处理,这些存根由 春云合同验证器。spring-doc.cadn.net.cn