WiremockClient is an HTTP client that allows users to interact with a standalone Wiremock instance from within an Xcode project.
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)))
WiremockClient maps closely to the functionality available in Wiremock's native Java API as described in the documentation. 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.
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 before using WiremockClient, or you will be unable to communicate with your standalone instance.
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:
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 portion of the documentation, so a full explanation will not be reproduced here. There are three significant differences to note:
stubFor()
method used to initialize a mapping in the Java API is now a type function of the StubMapping
class.aResponse()
method used to initialize a response object in the Java API has been replaced with an instance of the ResponseDefinition
class.stubFor
and aResponse
methods above must be passed to the WiremockClient.postMapping(stubMapping: StubMapping)
function to be posted to the standalone Wiremock instance.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 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:
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 documentation:
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:
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 documentation:
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.withPriority(1)
.willReturn(ResponseDefinition())
)
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 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:
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:
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)))
)
)
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 portion of the documentation:
WiremockClient.postMapping(stubMapping:
StubMapping.stubFor(requestMethod: .ANY, urlMatchCondition: .urlEqualTo, url: "http://localhost:8080/my/path")
.willReturn(
ResponseDefinition()
.proxiedFrom("http://myproxyhost.gov")
)
)
WiremockClient also supports scenarios as described in the Stateful Behavior portion of the documentation:
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”):
WiremockClient.resetAllScenarios()
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:
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)
)
)
Similar to updating a mapping, deleting a mapping requires a reference to it’s UUID:
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:
WiremockClient.reset()
Mappings can be persisted to the mappings
directory of your Wiremock instance via the following method:
WiremockClient.saveAllMappings()
A typical use case of WiremockClient looks like this:
WiremockClient.postMapping()
in the test suite’s setup()
method to post the required mappings before the app launches.WiremockClient.updateMapping()
within the test script to alter mappings on the fly.WiremockClient.reset()
in the test suite’s tearDown()
method to remove all mappings after the test has finished.Ted Rothrock, theodore.rothrock@gmail.com
WiremockClient is available under the MIT license. See the LICENSE file for more info.