mobileforming/wiremockclient
WiremockClient is an HTTP client that allows users to interact with a standalone Wiremock instance from within an Xcode project.
Installation
WiremockClient is available through CocoaPods and Swift Package Manager.
To install with CocoaPods, simply add the following line to your Podfile:
pod "WiremockClient"To install with SwiftPM, add the following line to the dependencies section of your Package.swift:
.package(url: "https://github.com/mobileforming/WiremockClient", .upToNextMajor(from: Version(major: 2, minor: 2, patch: 0)))Usage
WiremockClient maps closely to the functionality available in Wiremock's native Java API as described in the [documentation](http://wiremock.org/docs/). The pod enables you to build and post JSON mappings to a standalone Wiremock instance from within an Xcode project. It is assumed that you are familiar with the basics of using Wiremock, including initializing a standalone instance and populating it with mappings.
### Getting Started
To begin using WiremockClient, start up a standalone Wiremock instance on localhost port 8080. The base URL for all requests is set to `http://localhost:8080` by default and can be modified at the top of the `WiremockClient` file. Be sure to [whitelist your base URL](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33) before using WiremockClient, or you will be unable to communicate with your standalone instance.
### Posting a Mapping
The following code will post a mapping to your Wiremock standalone instance that will match any request sent to the `http://localhost:8080/my/path` endpoint and return a status of 200:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
```
This behavior maps closely to the Java API as described in the [Stubbing](http://wiremock.org/docs/stubbing/) portion of the documentation, so a full explanation will not be reproduced here. There are three significant differences to note:
1. The `stubFor()` method used to initialize a mapping in the Java API is now a type function of the `StubMapping` class.
2. The `aResponse()` method used to initialize a response object in the Java API has been replaced with an instance of the `ResponseDefinition` class.
3. The mapping created using the `stubFor` and `aResponse` methods above must be passed to the `WiremockClient.postMapping(stubMapping: StubMapping)` function to be posted to the standalone Wiremock instance.
### Matching a Request
All of the request matching logic available in the Java API has been reproduced within WiremockClient. For a full explanation of the methods below, reference the [Request Matching](http://wiremock.org/docs/request-matching/) portion of the documentation.
A collection of `StubMapping` instance methods enable the user to build mappings step-by-step, specifying the criteria that must be met in order for an incoming network request to be considered a match:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost: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()
)
)
```
An additional `withRequestBodyEqualToJson` method has been added to allow users to set the `ignoreArrayOrder` and `ignoreExtraElements` flags described in the ‘JSON equality’ section of the [Request Matching](http://wiremock.org/docs/request-matching/) documentation:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withRequestBodyEqualToJson(jsonString: "{ \"total_results\": 4 }", ignoreArrayOrder: true, ignoreExtraElements: true)
.willReturn(ResponseDefinition())
)
```
WiremockClient also includes a convenience method for stubbing request JSON that is stored in a local file:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withRequestBodyFromLocalJsonFile(fileName: "myFile", in: Bundle(for: type(of: self)))
.willReturn(ResponseDefinition())
)
```
Mappings can also be prioritized as described in the ‘Stub priority’ section of the [Stubbing](http://wiremock.org/docs/stubbing/) documentation:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withPriority(1)
.willReturn(ResponseDefinition())
)
```
### Defining a Response
All of the response definition logic available in the Java API has been reproduced in WiremockClient. For a full explanation of the methods below, reference the [Stubbing](http://wiremock.org/docs/stubbing/) portion of the documentation.
A collection of `ResponseDefinition` instance methods enable the user to specify elements to include in the response that is returned when a mapping is matched:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost: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 also includes a convenience method for returning JSON that is stored in a local file:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.willReturn(
ResponseDefinition()
.withLocalJsonBodyFile(fileName: "myFile", in: Bundle(for: type(of: self)))
)
)
```
### Proxying
As in the Java API, requests can be proxied through to other hosts. A full explanation of this method can be found in the [Proxying](http://wiremock.org/docs/proxying/) portion of the documentation:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.willReturn(
ResponseDefinition()
.proxiedFrom("http://myproxyhost.gov")
)
)
```
### Stateful Behavior
WiremockClient also supports scenarios as described in the [Stateful Behavior](http://wiremock.org/docs/stateful-behaviour/) portion of the documentation:
```swift
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.inScenario("Scenario Title")
.whenScenarioStateIs("Required Scenario State")
.willSetStateTo("New Scenario State")
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
```
The following method resets all scenarios to their default state (“Started”):
```swift
WiremockClient.resetAllScenarios()
```
### Updating a Mapping
Updating a mapping requires a reference to it’s UUID. When a mapping is created, a UUID is automatically assigned to it. However, it is also possible to assign a UUID manually and cache it in a variable for future reference. In the example below, a mapping is posted that returns a status code of 200 when matched. The mapping is then updated to return a status code of 404:
```swift
let myMappingID = UUID()
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withUUID(myMappingID)
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
WiremockClient.updateMapping(uuid: myMappingID, stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.willReturn(
ResponseDefinition()
.withStatus(404)
)
)
```
### Deleting Mappings
Similar to updating a mapping, deleting a mapping requires a reference to it’s UUID:
```swift
let myMappingID = UUID()
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .GET, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withUUID(myMappingID)
.willReturn(
ResponseDefinition()
.withStatus(200)
)
)
WiremockClient.deleteMapping(uuid: myMappingID)
```
It is also possible to reset your Wiremock instance by deleting all mappings simultaneously:
```swift
WiremockClient.reset()
```
### Saving Mappings
Mappings can be persisted to the `mappings` directory of your Wiremock instance via the following method:
```swift
WiremockClient.saveAllMappings()
```
### Using WiremockClient in an XCTestCase
A typical use case of WiremockClient looks like this:
1. Call `WiremockClient.postMapping()` in the test suite’s `setup()` method to post the required mappings before the app launches.
2. If necessary, call `WiremockClient.updateMapping()` within the test script to alter mappings on the fly.
3. Call `WiremockClient.reset()` in the test suite’s `tearDown()` method to remove all mappings after the test has finished.License
WiremockClient is available under the MIT license. See the LICENSE file for more info.
Package Metadata
Repository: mobileforming/wiremockclient
Default branch: master
README: README.md