Stub Runner Core

存根运行器内核会为服务合作者运行存根。将存根视为服务的合约允许您使用存根运行器作为 Consumer-driven Contracts 的实现。 Stub Runner 允许您自动下载所提供依赖项的 stub(或从类路径中选择那些),为它们启动 WireMock 服务器,并使用适当的 stub 定义为它们提供支持。对于消息传递,将定义特殊的 stub 路由。

Retrieving stubs

您可以从以下获取 stub 的选项中进行选择:

  • 基于 Aether 的解决方案,从 Artifactory 或 Nexus 下载包含存根的 JAR

  • 类路径扫描解决方案,使用模式搜索类路径以检索存根

  • 编写你自己的 org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder 的实现以获得完全定制

后一个示例在 Custom Stub Runner 部分中进行说明了。

Downloading Stubs

您可以使用 stubsMode 开关控制 stub 的下载。它从 StubRunnerProperties.StubsMode 枚举中选择值。您可以使用以下选项:

  • StubRunnerProperties.StubsMode.CLASSPATH(默认值):从类路径中挑选存根

  • StubRunnerProperties.StubsMode.LOCAL:从本地存储挑选存根(例如,.m2

  • StubRunnerProperties.StubsMode.REMOTE:从远程位置挑选存根

以下示例从本地位置选择 stub:

@AutoConfigureStubRunner(repositoryRoot="https://foo.bar", ids = "com.example:beer-api-producer:+:stubs:8095", stubsMode = StubRunnerProperties.StubsMode.LOCAL)

Classpath scanning

如果您将 stubsMode 属性设置为 StubRunnerProperties.StubsMode.CLASSPATH(或不设置任何内容,因为 CLASSPATH 是默认值),则扫描类路径。考虑以下示例:

@AutoConfigureStubRunner(ids = {
    "com.example:beer-api-producer:+:stubs:8095",
    "com.example.foo:bar:1.0.0:superstubs:8096"
})

您可以将依赖项添加到类路径,如下所示:

Maven
<dependency>
    <groupId>com.example</groupId>
    <artifactId>beer-api-producer-restdocs</artifactId>
    <classifier>stubs</classifier>
    <version>0.0.1-SNAPSHOT</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.example.thing1</groupId>
    <artifactId>thing2</artifactId>
    <classifier>superstubs</classifier>
    <version>1.0.0</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Gradle
testCompile("com.example:beer-api-producer-restdocs:0.0.1-SNAPSHOT:stubs") {
    transitive = false
}
testCompile("com.example.thing1:thing2:1.0.0:superstubs") {
    transitive = false
}

然后,扫描类路径上的指定位置。对于 com.example:beer-api-producer-restdocs,扫描以下位置:

  • /META-INF/com.example/beer-api-producer-restdocs/*/.*

  • /contracts/com.example/beer-api-producer-restdocs/*/.*

  • /mappings/com.example/beer-api-producer-restdocs/*/.*

对于 com.example.thing1:thing2,扫描以下位置:

  • /META-INF/com.example.thing1/thing2/*/.*

  • /contracts/com.example.thing1/thing2/*/.*

  • /mappings/com.example.thing1/thing2/*/.*

在你打包producer stub时,必须明确提供组和artifact id。

为实现适当的 stub 打包,生产者将按照如下方式设置合同:

└── src
    └── test
        └── resources
            └── contracts
                └── com.example
                    └── beer-api-producer-restdocs
                        └── nested
                            └── contract3.groovy

通过使用 Maven assembly pluginGradle Jar 任务,您必须在自己的存根 jar 中创建以下结构:

└── META-INF
    └── com.example
        └── beer-api-producer-restdocs
            └── 2.0.0
                ├── contracts
                │   └── nested
                │       └── contract2.groovy
                └── mappings
                    └── mapping.json

通过维护此结构,将扫描类路径并且无需下载工件即可从消息传递或 HTTP 存根中获益。

Configuring HTTP Server Stubs

Stub Runner 有一个 HttpServerStub 的概念,它抽象了底层 HTTP 服务器的具体实现(例如,WireMock 是实现之一)。有时,您需要对存根服务器执行一些附加的调整(这对给定的实现是具体的)。要做到这一点,Stub Runner 为您提供了 httpServerStubConfigurer 属性,该属性在注释和 JUnit 规则中可用,并且可以通过系统属性进行访问,您可以在其中提供 org.springframework.cloud.contract.stubrunner.HttpServerStubConfigurer 接口的实现。这些实现可以更改给定 HTTP 服务器存根的配置文件。

Spring Cloud Contract Stub Runner 带有一个可以针对 WireMock 扩展的实现:org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStubConfigurer。在 configure 方法中,您可以提供给定存根自己的自定义配置。用例可能是针对给定的工件 ID 在 HTTPS 端口上启动 WireMock。以下示例演示如何执行此操作:

Example 1. WireMockHttpServerStubConfigurer implementation
link:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[role=include]

然后,您可以使用 @AutoConfigureStubRunner 注释对其进行重复使用,如下所示:

link:{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[role=include]

每当找到 HTTPS 端口时,它都优先于 HTTP 端口。

Running stubs

本节介绍了如何运行存根。它包含以下主题:

HTTP Stubs

存根使用 JSON 文档进行定义,其语法由 WireMock documentation 中定义。

以下示例在 JSON 中定义了一个存根:

{
    "request": {
        "method": "GET",
        "url": "/ping"
    },
    "response": {
        "status": 200,
        "body": "pong",
        "headers": {
            "Content-Type": "text/plain"
        }
    }
}

Viewing Registered Mappings

每个存根的合作者都会在 __/admin/ 端点下公开一个已定义的映射列表。

您还可以使用 mappingsOutputFolder 属性将映射转储到文件中。对于基于注释的方法,它类似于以下示例:

@AutoConfigureStubRunner(ids="a.b.c:loanIssuance,a.b.c:fraudDetectionServer",
mappingsOutputFolder = "target/outputmappings/")

对于 JUnit 方法,它类似于以下示例:

@ClassRule @Shared StubRunnerRule rule = new StubRunnerRule()
			.repoRoot("https://some_url")
			.downloadStub("a.b.c", "loanIssuance")
			.downloadStub("a.b.c:fraudDetectionServer")
			.withMappingsOutputFolder("target/outputmappings")

然后,如果您签出 target/outputmappings 文件夹,您将看到以下结构;

.
├── fraudDetectionServer_13705
└── loanIssuance_12255

这意味着注册了两个存根。fraudDetectionServer 在端口 13705 注册,loanIssuance 在端口 12255 注册。如果我们查看其中一个文件,我们将看到(对于 WireMock)给定服务器可用的映射:

[{
  "id" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7",
  "request" : {
    "url" : "/name",
    "method" : "GET"
  },
  "response" : {
    "status" : 200,
    "body" : "fraudDetectionServer"
  },
  "uuid" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7"
},
...
]

Messaging Stubs

根据提供的 Stub Runner 依赖和 DSL,消息传递路由会自动设置。