WiremockClient
WiremockClient 是一个 HTTP 客户端,允许用户在 Xcode 项目中与独立的 Wiremock 实例进行交互。
安装
WiremockClient 通过 CocoaPods 和 Swift Package Manager 提供。
使用 CocoaPods 安装,只需将以下行添加到 Podfile
pod "WiremockClient"
使用 SwiftPM 安装,将以下行添加到 Package.swift 的 dependencies
部分
.package(url: "https://github.com/mobileforming/WiremockClient", .upToNextMajor(from: Version(major: 2, minor: 2, patch: 0)))
用法
WiremockClient 与 Wiremock 的原生 Java API 提供的功能相对应,如文档所述。该 pod 允许您在 Xcode 项目中构建并将 JSON 映射发送到一个独立的 Wiremock 实例。假设您熟悉使用 Wiremock 的基础知识,包括初始化一个独立实例并将其用映射填充。
开始使用
要开始使用WiremockClient,请在本地host端口8080上启动一个独立的Wiremock实例。默认情况下,所有请求的基础URL设置为https://:8080
,可以在WiremockClient
文件顶部进行修改。在使用WiremockClient之前,务必将基础URL添加到白名单,否则您将无法与独立的实例进行通信。
发布映射
以下代码将发布一个映射到您的Wiremock独立实例,该映射将匹配任何发送到https://:8080/my/path
端点的请求,并返回状态码200。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
此行为与文档中“模拟”部分的Java API紧密映射,因此此处不会重复全文解释。需要注意的是三个显著的差异:
- 在Java API中用于初始化映射的
stubFor()
方法现在变为StubMapping
类的类型函数。 - 在Java API中用于初始化响应对象的
aResponse()
方法已被ResponseDefinition
类的一个实例所替代。 - 使用上述
stubFor
和aResponse
方法创建的映射必须传递给WiremockClient.postMapping(stubMapping: StubMapping)
函数,才能发布到独立Wiremock实例。
匹配请求
WiremockClient中包含了Java API中可用的所有请求匹配逻辑。关于以下方法的完整解释,请参考文档中“请求匹配”部分。
一组StubMapping
实例方法允许用户逐步构建映射,指定必须满足的条件,以便将传入的网络请求视为匹配项。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withHeader("Accept", matchCondition: .contains, value: "xml")
.withCookie("session", matchCondition: .matches, value: ".*12345.*")
.withQueryParam("search_term", matchCondition: .equalTo, value: "WireMock")
.withBasicAuth(username: "myUsername", password: "myPassword")
.withRequestBody(.equalTo, value: "Some request body string")
.willReturn(
ResponseDefinition()
)
)
新增的withRequestBodyEqualToJson
方法允许用户设置在请求匹配文档中“JSON等价”部分所述的ignoreArrayOrder
和ignoreExtraElements
标志。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withRequestBodyEqualToJson(jsonString: "{ \"total_results\": 4 }", ignoreArrayOrder: true, ignoreExtraElements: true)
.willReturn(ResponseDefinition())
)
WiremockClient还包括一个方便的方法,用于模拟存储在本地文件中的请求JSON。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withRequestBodyFromLocalJsonFile(fileName: "myFile", in: Bundle(for: type(of: self)))
.willReturn(ResponseDefinition())
)
映射也可以按照文档中“模拟优先级”部分所述进行优先级排序。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withPriority(1)
.willReturn(ResponseDefinition())
)
定义响应
Java API中可用的所有响应定义逻辑已复現在WiremockClient之中。关于以下方法的完整解释,请参阅文档中存根部分。
一系列的ResponseDefinition
实例方法可以使用户指定在匹配映射时返回的响应中应包含的元素
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.willReturn(
ResponseDefinition()
.withStatus(200)
.withStatusMessage("Great jorb!")
.withHeaders(["Pragma": "no-cache", "Connection": "keep-alive"])
.withBody("Just a plain old text body")
)
)
WiremockClient还包括一个方便的方法来返回保存在本地文件中的JSON
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.willReturn(
ResponseDefinition()
.withLocalJsonBodyFile(fileName: "myFile", in: Bundle(for: type(of: self)))
)
)
代理
与Java API类似,请求可以代理到其他主机。关于此方法的完整解释,请参阅文档中的代理部分。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.willReturn(
ResponseDefinition()
.proxiedFrom("http://myproxyhost.gov")
)
)
状态化行为
WiremockClient还支持文档中状态化行为部分所述的场景。
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.inScenario("Scenario Title")
.whenScenarioStateIs("Required Scenario State")
.willSetStateTo("New Scenario State")
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
以下方法将所有场景重置为其默认状态(“启动”)
WiremockClient.resetAllScenarios()
更新映射
更新映射需要对其UUID的引用。创建映射时,会自动为其分配一个UUID。然而,还可以手动分配一个UUID,并将其保存在变量中以供将来引用。以下示例中,一个映射被发送以返回匹配时状态码为200。然后将该映射更新为返回状态码为404。
let myMappingID = UUID()
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withUUID(myMappingID)
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
WiremockClient.updateMapping(uuid: myMappingID, stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.willReturn(
ResponseDefinition()
.withStatus(404)
)
)
删除映射
与更新映射类似,删除映射也需要对其UUID的引用。
let myMappingID = UUID()
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "https://:8080/my/path")
.withUUID(myMappingID)
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
WiremockClient.deleteMapping(uuid: myMappingID)
还可能通过同时删除所有映射来重置您的Wiremock实例
WiremockClient.reset()
保存映射
可以通过以下方式将映射持久化到Wiremock实例的mappings
目录:
WiremockClient.saveAllMappings()
在XCTestCase中使用WiremockClient
WiremockClient的典型用法如下:
- 在测试套件的
setup()
方法中调用WiremockClient.postMapping()
,在应用启动前发布所需的映射。 - 如果需要,在测试脚本中调用
WiremockClient.updateMapping()
以动态更改映射。 - 在测试套件的
tearDown()
方法中调用WiremockClient.reset()
,在测试结束后移除所有映射。
作者
Ted Rothrock, [email protected]
许可协议
WiremockClient遵循MIT许可协议。有关更多信息,请参阅LICENSE文件。