Maven项目

添加 Maven 插件

要添加春云合同物料清单,请在您的文件中包含以下部分pom.xml文件:spring-doc.cadn.net.cn

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-dependencies</artifactId>
	<version>${spring-cloud-contract.version}</version>
	<type>pom</type>
	<scope>import</scope>
</dependency>

接着,添加春云合约验证器Maven插件,具体如下:spring-doc.cadn.net.cn

<plugin>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
	<version>${spring-cloud-contract.version}</version>
	<extensions>true</extensions>
	<configuration>
		<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
	</configuration>
</plugin>

有时候,无论选择哪个IDE,你都能看到目标/生成测试源文件夹在IDE的类路径中不可见。为了确保它始终存在,你可以在你的pom.xmlspring-doc.cadn.net.cn

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>build-helper-maven-plugin</artifactId>
	<executions>
		<execution>
			<id>add-source</id>
			<phase>generate-test-sources</phase>
			<goals>
				<goal>add-test-source</goal>
			</goals>
			<configuration>
				<sources>
					<source>${project.build.directory}/generated-test-sources/contracts/</source>
				</sources>
			</configuration>
		</execution>
	</executions>
</plugin>

Maven 与 Rest Assured 2.0

默认情况下,Rest Assured 3.x 会被添加到类路径中。不过,你也可以用休息 通过将它添加到插件的类路径中,确保了 2.x,具体如下:spring-doc.cadn.net.cn

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>${spring-cloud-contract.version}</version>
    <extensions>true</extensions>
    <configuration>
        <packageWithBaseClasses>com.example</packageWithBaseClasses>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-contract-verifier</artifactId>
            <version>${spring-cloud-contract.version}</version>
        </dependency>
        <dependency>
           <groupId>com.jayway.restassured</groupId>
           <artifactId>rest-assured</artifactId>
           <version>2.5.0</version>
           <scope>compile</scope>
        </dependency>
        <dependency>
           <groupId>com.jayway.restassured</groupId>
           <artifactId>spring-mock-mvc</artifactId>
           <version>2.5.0</version>
           <scope>compile</scope>
        </dependency>
    </dependencies>
</plugin>

<dependencies>
    <!-- all dependencies -->
    <!-- you can exclude rest-assured from spring-cloud-contract-verifier -->
    <dependency>
       <groupId>com.jayway.restassured</groupId>
       <artifactId>rest-assured</artifactId>
       <version>2.5.0</version>
       <scope>test</scope>
    </dependency>
    <dependency>
       <groupId>com.jayway.restassured</groupId>
       <artifactId>spring-mock-mvc</artifactId>
       <version>2.5.0</version>
       <scope>test</scope>
    </dependency>
</dependencies>

这样插件会自动识别 Rest Assured 2.x 存在于类路径上 并相应地修改导入。spring-doc.cadn.net.cn

使用 Maven 的快照和里程碑版本

要使用快照和里程碑版本,你需要在你的表格中添加以下部分pom.xml:spring-doc.cadn.net.cn

<repositories>
	<repository>
		<id>spring-snapshots</id>
		<name>Spring Snapshots</name>
		<url>https://repo.spring.io/snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</repository>
	<repository>
		<id>spring-milestones</id>
		<name>Spring Milestones</name>
		<url>https://repo.spring.io/milestone</url>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</repository>
</repositories>
<pluginRepositories>
	<pluginRepository>
		<id>spring-snapshots</id>
		<name>Spring Snapshots</name>
		<url>https://repo.spring.io/snapshot</url>
		<snapshots>
			<enabled>true</enabled>
		</snapshots>
	</pluginRepository>
	<pluginRepository>
		<id>spring-milestones</id>
		<name>Spring Milestones</name>
		<url>https://repo.spring.io/milestone</url>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</pluginRepository>
</pluginRepositories>

添加小作品

默认情况下,Spring Cloud 合同验证器会在SRC/测试/资源/合同目录。包含存根定义的目录为 将其视为类名,每个存根定义被视为一个单一测试。我们假设 它至少包含一个用作测试类名称的目录。如果还有更多 在一层嵌套目录中,除最后一个外,其他都用作包名。 考虑以下结构:spring-doc.cadn.net.cn

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

在这种结构下,Spring Cloud Contract Verifier 创建了一个名为defaultBasePackage.MyService采用两种方法:spring-doc.cadn.net.cn

运行插件

生成测试插件目标被分配到称为生成测试源.如果你想让它成为你构建过程的一部分,就不必这么做 什么。如果你只想生成测试,可以调用生成测试目标。spring-doc.cadn.net.cn

如果你想查询Maven的存根,请致电执行带有存根的目标,作为spring.cloud.contract.verifier.stubs系统性质如下:spring-doc.cadn.net.cn

MVN org.Springframework.cloud:Spring-Cloud-Contract-Maven-Plugin:run \ -Dspring.cloud.contract.verifier.stubs=“com.acme:service-name”spring-doc.cadn.net.cn

配置插件

要更改默认配置,可以添加一个配置插件的部分 定义或执行定义如下:spring-doc.cadn.net.cn

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>convert</goal>
                <goal>generateStubs</goal>
                <goal>generateTests</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <basePackageForTests>org.springframework.cloud.verifier.twitter.place</basePackageForTests>
        <baseClassForTests>org.springframework.cloud.verifier.twitter.place.BaseMockMvcSpec</baseClassForTests>
    </configuration>
</plugin>

配置选项

  • 测试模式定义了验收测试的模式。默认情况下,模式为莫克麦克, 该项目基于Spring的MockMvc。你也可以改成WebTestClient,JaxRs客户端明确(用于真实的HTTP调用)。spring-doc.cadn.net.cn

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

  • ruleClassForTests: 指定应添加到生成测试中的规则 类。spring-doc.cadn.net.cn

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

  • 合同目录: 指定一个目录,包含用 Groovyn DSL。默认目录是/src/test/resources/contracts.spring-doc.cadn.net.cn

  • 生成测试源Dir: 指定测试源目录,生成测试 应该从Groovy DSL中放置。默认情况下,其值为$buildDir/生成测试源/合同.spring-doc.cadn.net.cn

  • 生成测试资源指令: 指定生成测试所使用的资源的测试资源目录。spring-doc.cadn.net.cn

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

  • packageWithBaseClasses定义了一个包,所有基类都存在。这 环境优先于环境baseClassForTests.惯例是,如果你 根据(例如)签订合同src/test/resources/contract/foo/bar/baz/并且集合 该packageWithBaseClasses属性到com.example.baseSpring 云合同验证器假设存在BarBazBasecom.example.base包。换句话说,系统取 如果有包,则构成一个类,满足基础作为后缀。spring-doc.cadn.net.cn

  • baseClassMappings: 指定了一组基类映射,满足以下条件contractPackageRegex(这会与合同所在的包进行核对 已定位)以及baseClassFQN( 映射到 的基类的全限定名称 匹配合同)。例如,如果你有一份合同,根据src/test/resources/contract/foo/bar/baz/并将映射.* → com.example.base.BaseClass属性,即由这些契约生成的测试类 延伸com.example.base.BaseClass.此设定优先于此packageWithBaseClassesbaseClassForTests.spring-doc.cadn.net.cn

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

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

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

  • 增量合同测试启用后,测试仅在合同自上次构建以来发生变化时创建。默认true.spring-doc.cadn.net.cn

  • 增量合同小作品: 启用后,只有在合同自上次构建以来发生变化时才会创建存根。默认true.spring-doc.cadn.net.cn

  • 增量合同存根启用后,存根jar仅在存根自上次构建以来发生变化时创建。默认true. *httpPort: 为提供存根的 WireMock 服务器提供 HTTP 端口。现在Spring.cloud.contract.verifier.http.port属性仅在目录中的存根服务时有效。否则,在提供存根 id 时,port 必须包含在 id 字符串中。 *:将此设为true以绕过验证器执行。 *skipTestOnly:将此设为true以绕过验证器测试生成。 *存根: 可下载并以冒号分隔的常春藤符号运行的存根列表。 *最小端口: 指定存根应从哪个端口起始。 *maxPort: 指定存根应从的最大端口起点。 *等待按键: 指定插件是否应等待用户在启动存根后按下按键。 *小作品分类器: 指定了存根工件所使用的分类器。spring-doc.cadn.net.cn

如果你想从 Maven 仓库下载你的合同定义,你可以使用 以下选项:spring-doc.cadn.net.cn

  • 合同依赖关系:包含所有打包合同的契约依赖关系。spring-doc.cadn.net.cn

  • 合同路径:通过打包合同,JAR中通往混凝土合同的路径。 默认Groupid/Artifactid哪里格罗普伊德是分开的。spring-doc.cadn.net.cn

  • 合同模式: 选择存根的查找和注册模式。spring-doc.cadn.net.cn

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

  • contractsRepositoryUrl: 包含有契约的工件仓库的网址。如果没有提供, 用现在的Maven版本。spring-doc.cadn.net.cn

  • contractsRepository用户名:用于连接仓库并签订合同的用户名。spring-doc.cadn.net.cn

  • contractsRepositoryPassword(合约仓库密码):用于连接仓库的密码。spring-doc.cadn.net.cn

  • contractsRepositoryProxyHost:用于通过合同连接仓库的代理主机。spring-doc.cadn.net.cn

  • contractsRepositoryProxyPort:用于连接仓库的代理端口。spring-doc.cadn.net.cn

我们只缓存非快照、明确提供的版本(例如或+1.0.0.构建快照不要被缓存)。默认情况下,此功能是开启的。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

所有测试均采用单一基质

当默认使用 Spring Cloud 合约验证器时 (莫克麦克你需要建立一个基础 所有生成验收测试的规范。在这门课中,你需要指向一个 端点,应该经过验证。以下示例展示了如何实现:spring-doc.cadn.net.cn

import org.mycompany.ExampleSpringController
import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc
import spock.lang.Specification

class MvcSpec extends Specification {
  def setup() {
   RestAssuredMockMvc.standaloneSetup(new ExampleSpringController())
  }
}

如有必要,您还可以设置整个上下文,如下示例所示:spring-doc.cadn.net.cn

import io.restassured.module.mockmvc.RestAssuredMockMvc;
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.test.context.junit4.SpringRunner;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = SomeConfig.class, properties="some=property")
public abstract class BaseTestClass {

	@Autowired
	WebApplicationContext context;

	@Before
	public void setup() {
		RestAssuredMockMvc.webAppContextSetup(this.context);
	}
}

如果你使用,明确模式,你可以用基类初始化整个测试应用, 类似于你在普通积分测试中可能做的事情。以下示例显示 如何作:spring-doc.cadn.net.cn

import io.restassured.RestAssured;
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.boot.web.server.LocalServerPort;
import org.springframework.web.context.WebApplicationContext;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = SomeConfig.class, properties="some=property")
public abstract class BaseTestClass {

	@LocalServerPort
	int port;

	@Before
	public void setup() {
		RestAssured.baseURI = "http://localhost:" + this.port;
	}
}

如果你使用了JAXRS客户端该基类还应包含一个受保护的WebTarget webTarget田。右 现在,测试JAX-RS API的唯一方法是启动一个网络服务器。spring-doc.cadn.net.cn

使用不同的基类来签订合同

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

按惯例

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

<plugin>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
	<configuration>
		<packageWithBaseClasses>hello</packageWithBaseClasses>
	</configuration>
</plugin>

按制图方式

你可以手动将合同包的正则表达式映射到完全合格的 匹配合同的基础类名称。你必须提供一份叫做baseClassMappingsbaseClassMapping每个对象contractPackageRegexbaseClassFQN映射。请考虑以下例子:spring-doc.cadn.net.cn

<plugin>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
	<configuration>
		<baseClassForTests>com.example.FooBase</baseClassForTests>
		<baseClassMappings>
			<baseClassMapping>
				<contractPackageRegex>.*com.*</contractPackageRegex>
				<baseClassFQN>com.example.TestBase</baseClassFQN>
			</baseClassMapping>
		</baseClassMappings>
	</configuration>
</plugin>

假设你在以下两个地点签订了合同:spring-doc.cadn.net.cn

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

调用生成测试

Spring Cloud Contract Maven 插件在一个名为/generated-test-sources/contractVerifier并将此目录附加于测试编译目标。spring-doc.cadn.net.cn

对于Groovy Spock代码,您可以使用以下工具:spring-doc.cadn.net.cn

<plugin>
	<groupId>org.codehaus.gmavenplus</groupId>
	<artifactId>gmavenplus-plugin</artifactId>
	<version>1.5</version>
	<executions>
		<execution>
			<goals>
				<goal>testCompile</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<testSources>
			<testSource>
				<directory>${project.basedir}/src/test/groovy</directory>
				<includes>
					<include>**/*.groovy</include>
				</includes>
			</testSource>
			<testSource>
				<directory>${project.build.directory}/generated-test-sources/contractVerifier</directory>
				<includes>
					<include>**/*.groovy</include>
				</includes>
			</testSource>
		</testSources>
	</configuration>
</plugin>

为了确保提供者端遵守定义的合同,你需要调用mvn generateTest 测试.spring-doc.cadn.net.cn

向SCM推送小作品

如果你使用 SCM(源控管理)仓库来保存合同和 存根,你可能想自动化推送存根的步骤 仓库。为此,你可以添加pushStubsToScm目标。以下示例展示了如何实现:spring-doc.cadn.net.cn

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>${spring-cloud-contract.version}</version>
    <extensions>true</extensions>
    <configuration>
        <!-- Base class mappings etc. -->

        <!-- We want to pick contracts from a Git repository -->
        <contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git</contractsRepositoryUrl>

        <!-- We reuse the contract dependency section to set up the path
        to the folder that contains the contract definitions. In our case the
        path will be /groupId/artifactId/version/contracts -->
        <contractDependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>${project.artifactId}</artifactId>
            <version>${project.version}</version>
        </contractDependency>

        <!-- The contracts mode can't be classpath -->
        <contractsMode>REMOTE</contractsMode>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <!-- By default we will not push the stubs back to SCM,
                you have to explicitly add it as a goal -->
                <goal>pushStubsToScm</goal>
            </goals>
        </execution>
    </executions>
</plugin>

“使用SCM存根下载器”中,你可以找到所有可能的资源 你可以通过的配置选项 这<configuration><contractsProperties>映射,系统属性, 或者环境变量。例如,你可以指定一个具体的分支来结出,而不是默认的spring-doc.cadn.net.cn

<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>${spring-cloud-contract.version}</version>
    <extensions>true</extensions>
    <configuration>
        <!-- Base class mappings etc. -->

        <!-- We want to pick contracts from a Git repository -->
        <contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git</contractsRepositoryUrl>
	<contractsProperties>
            <git.branch>another_branch</git.branch>
        </contractsProperties>

        <!-- We reuse the contract dependency section to set up the path
        to the folder that contains the contract definitions. In our case the
        path will be /groupId/artifactId/version/contracts -->
        <contractDependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>${project.artifactId}</artifactId>
            <version>${project.version}</version>
        </contractDependency>

        <!-- The contracts mode can't be classpath -->
        <contractsMode>REMOTE</contractsMode>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <!-- By default we will not push the stubs back to SCM,
                you have to explicitly add it as a goal -->
                <goal>pushStubsToScm</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Maven插件和STS

下图展示了你使用STS时可能看到的一个例外:spring-doc.cadn.net.cn

STS例外

点击错误标记时,你应该会看到类似这样的内容:spring-doc.cadn.net.cn

 plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
 cloud-contract-maven-plugin:1.1.0.M1:convert failed. at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145) at
 org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:331) at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1362) at
...
 org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) Caused by: java.lang.NullPointerException at
 org.eclipse.m2e.core.internal.builder.plexusbuildapi.EclipseIncrementalBuildContext.hasDelta(EclipseIncrementalBuildContext.java:53) at
 org.sonatype.plexus.build.incremental.ThreadBuildContext.hasDelta(ThreadBuildContext.java:59) at

要解决这个问题,请在你的pom.xml:spring-doc.cadn.net.cn

<build>
    <pluginManagement>
        <plugins>
            <!--This plugin's configuration is used to store Eclipse m2e settings
                only. It has no influence on the Maven build itself. -->
            <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                             <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>org.springframework.cloud</groupId>
                                    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
                                    <versionRange>[1.0,)</versionRange>
                                    <goals>
                                        <goal>convert</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <execute />
                                </action>
                             </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

Maven 插件与 Spock 测试

你可以选择Spock框架来创建和运行自动生成的合同 验证测试同时使用Maven和Gradle。不过,虽然使用 Gradle 很简单, 在Maven中,你需要额外的设置,才能让测试正确编译和执行。spring-doc.cadn.net.cn

首先,你必须使用插件,比如 GMavenPlus 插件, 把Groovy加入你的项目。在GMavenPlus插件中,你需要明确设置测试源,包括两个 路径,定义了你的基础测试类,以及生成的契约测试添加路径。 以下示例展示了如何实现这一点。spring-doc.cadn.net.cn

如果你遵循斯波克惯例,将测试类名称以规范你还需要调整你的Maven Surefire插件设置,正如下面的示例所示。spring-doc.cadn.net.cn