Spring Cloud Contract WireMock
Spring Cloud Contract WireMock 模块允许你在 Spring Boot 应用程序中使用 WireMock。 有关详细信息,请查看 Spring Cloud Contract 的存储库 samples subfolder。
如果你有一个将 Tomcat 用作嵌入式服务器(这在 spring-boot-starter-web
中是默认的)的 Spring Boot 应用程序,你可以向你的类路径添加 spring-cloud-starter-contract-stub-runner
,并添加 @AutoConfigureWireMock
,以便在你的测试中使用 Wiremock。Wiremock 以存根服务器运行,并且你可以使用 Java API 或使用静态 JSON 声明作为你测试的一部分来注册存根行为。
要在不同的端口上启动存根服务器,请使用(例如)@AutoConfigureWireMock(port=9999)
。对于随机端口,使用值为 0
。存根服务器端口可以使用 wiremock.server.port
属性在测试应用程序上下文中绑定。使用 @AutoConfigureWireMock
将 WiremockConfiguration
类型的一个 bean 添加到你的测试应用程序上下文中,其中它被缓存在具有相同上下文的那些方法和类之间。Spring 集成测试也是这样。此外,你可以将 WireMockServer
类型的一个 bean 注入到你的测试中。在每个测试类之后,都会重置已注册的 WireMock 服务器。不过,如果你需要在每个测试方法之后重置它,请将 wiremock.reset-mappings-after-each-test
属性设置为 true
。
Registering Stubs Automatically
如果你使用 @AutoConfigureWireMock
,它将从文件系统或类路径(默认情况下,从 file:src/test/resources/mappings
)注册 WireMock JSON stub。你可以通过在注释中使用 stubs
属性来自定义位置,它可以是 Ant 样式资源模式或目录。如果是目录,则追加 */.json
。以下代码显示了一个示例:
@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureWireMock(stubs="classpath:/stubs") public class WiremockImportApplicationTests { @Autowired private Service service; @Test public void contextLoads() throws Exception { assertThat(this.service.go()).isEqualTo("Hello World!"); } }
实际上,WireMock 始终从 as
well as |
此外,`stubs`位置中的映射不被视为 Wiremock 的“默认映射”的一部分,并且在测试期间调用`com.github.tomakehurst.wiremock.client.WireMock.resetToDefaultMappings`不会导致`stubs`位置中的映射被包含在内。但是,`org.springframework.cloud.contract.wiremock.WireMockTestExecutionListener`在每次测试类之后确实会重置映射(包括添加来自存根位置的映射),还可以选择在每次测试方法之后(由`wiremock.reset-mappings-after-each-test`属性保护)重置映射。 |
如果你使用 Spring Cloud Contract 的默认存根 jar,则你的存根将存储在 /META-INF/group-id/artifact-id/versions/mappings/
文件夹中。如果你想从该位置注册所有存根,从所有嵌入的 JAR 中,可以使用以下语法:
Unresolved directive in project-features-wiremock.adoc - include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java[]
Using Files to Specify the Stub Bodies
WireMock 可以从类路径或文件系统上的文件读取响应主体。在文件系统的情况下,你可以在 JSON DSL 中看到响应具有 bodyFileName
而不是(文字)body
。这些文件相对于根目录(默认情况下为 src/test/resources/files
)解析。要自定义此位置,可以将 @AutoConfigureWireMock
注释中的 files
属性设置为父目录的位置(换句话说,files
是子目录)。你可以使用 Spring 资源符号来引用 file:…
或 classpath:…
位置。不支持通用 URL。可以给出值列表——在这种情况下,WireMock 将在需要查找响应主体时解析第一个存在的文件。
当您配置`files`根目录时,它也会影响存根的自动加载,因为它们来自名为`mappings`的子目录中的根目录位置。 |
`files`的值不会影响从`stubs`属性中显式加载的存根。 |
Alternative: Using JUnit Rules
Для более привычного восприятия WireMock вы можете использовать JUnit @Rules
для запуска и остановки сервера. Для этого используйте удобный класс WireMockSpring
для получения экземпляра Options
, как показано в следующем [примере] {doc_samples_url}:
@ClassRule
意味着服务器将在运行该类中的所有方法后关闭。
Relaxed SSL Validation for Rest Template
WireMock 允许你使用 https
URL 协议存根一个“安全”服务器。如果你的应用程序想在集成测试中与该存根服务器联系,它会发现 SSL 证书无效(自安装证书的常见问题)。通常最好的选择是重新配置客户端以使用 http
。如果那不是一个选项,你可以让 Spring 配置一个忽略 SSL 验证错误的 HTTP 客户端(当然,只针对测试)。
为了最小的麻烦让此工作,你需要在你的应用程序中使用 Spring Boot RestTemplateBuilder
,如下面的示例所示:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
你需要 RestTemplateBuilder
,因为构建器通过回调传递进行初始化,因此可以在那时在客户端中设置 SSL 验证。如果你使用 @AutoConfigureWireMock
注释或存根运行器,这会自动在你的测试中发生。如果你使用 JUnit @Rule
方法,则还需要添加 @AutoConfigureHttpClient
注释,如下面的示例所示:
@RunWith(SpringRunner.class)
@SpringBootTest("app.baseUrl=https://localhost:6443")
@AutoConfigureHttpClient
public class WiremockHttpsServerApplicationTests {
@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(
WireMockSpring.options().httpsPort(6443));
...
}
如果你使用 spring-boot-starter-test
,则你将类路径上具有 Apache HTTP 客户端,并且它是由 RestTemplateBuilder
选择并配置为忽略 SSL 错误的。如果你使用默认的 java.net
客户端,则不需要注释(但它没有危害)。目前不支持其他客户端,但可能会在以后的版本中添加。
要禁用自定义 RestTemplateBuilder
,请将 wiremock.rest-template-ssl-enabled
属性设置为 false
。
WireMock and Spring MVC Mocks
Spring Cloud Contract предоставляет удобный класс, который может загружать заглушки WireMock JSON в Spring MockRestServiceServer
. Это показано в следующем [проекте] {doc_samples_url}.
Значение baseUrl
добавляется в начало всех фиктивных вызовов, а метод stubs()
принимает в качестве аргумента шаблон ресурса пути заглушки. В приведенном выше примере в фиктивный сервер загружается заглушка, определенная в /stubs/resource.json
. Если RestTemplate`запрашивает посещение `https://example.org/
, он получает ответы, объявленные по этому URL-адресу. Можно указать более одного шаблона заглушки, каждый из которых может быть каталогом (для рекурсивного списка всех .json
), фиксированным именем файла (как в приведенном примере) или шаблоном в стиле Ant. Формат JSON — это обычный формат WireMock, который можно прочитать по адресу WireMock website.
目前,Spring Cloud Contract Verifier 支持 Tomcat、Jetty 和 Undertow 作为 Spring Boot 嵌入式服务器,而 Wiremock 本身对特定版本的 Jetty(当前为 9.2)具有“本机”支持。要使用本机 Jetty,需要添加本机 Wiremock 依赖项并排除 Spring Boot 容器(如果有)。