Proxying
WireMock has the ability to selectively proxy requests through to other hosts. This supports a proxy/intercept setup where requests are by default proxied to another (possibly real, live) service, but where specific stubs are configured these are returned in place of the remote service’s response. Responses that the live service can’t be forced to generate on demand can thus be injected for testing. Proxying also supports record and playback.
Proxy stub mappings
Proxy responses are defined in exactly the same manner as stubs, meaning that the same request matching criteria can be used.
The following code will proxy all GET requests made to
http://<host>:<port>/other/service/.*
to
http://otherservice.com/approot
, e.g. when running WireMock locally a
request to http://localhost:8080/other/service/doc/123
would be
forwarded to http://otherservice.com/approot/other/service/doc/123
.
stubFor(get(urlMatching("/other/service/.*"))
.willReturn(aResponse().proxiedFrom("http://otherhost.com/approot")));
The JSON equivalent would be:
{
"request": {
"method": "GET",
"urlPattern": "/other/service/.*"
},
"response": {
"proxyBaseUrl" : "http://otherhost.com/approot"
}
}
Proxy/intercept
The proxy/intercept pattern described above is achieved by adding a low priority proxy mapping with a broad URL match and any number of higher priority stub mappings e.g.
// Low priority catch-all proxies to otherhost.com by default
stubFor(get(urlMatching(".*")).atPriority(10)
.willReturn(aResponse().proxiedFrom("http://otherhost.com")));
// High priority stub will send a Service Unavailable response
// if the specified URL is requested
stubFor(get(urlEqualTo("/api/override/123")).atPriority(1)
.willReturn(aResponse().withStatus(503)));
Additional headers
It is possible to configure the proxy to add headers before forwarding the request to the destination:
// Inject user agent to trigger rendering of mobile version of website
stubFor(get(urlMatching(".*"))
.willReturn(aResponse()
.proxiedFrom("http://otherhost.com")
.withAdditionalRequestHeader("User-Agent", "Mozilla/5.0 (iPhone; U; CPU iPhone)"));
or
{
"request": {
"method": "GET",
"urlPattern": ".*"
},
"response": {
"proxyBaseUrl" : "http://otherhost.com",
"additionalProxyRequestHeaders": {
"User-Agent": "Mozilla/5.0 (iPhone; U; CPU iPhone)",
}
}
}
You can also add response headers via the same method as for non-proxy responses (see Stubbing).
Standalone shortcut
It is possible to start the standalone running with the catch-all stub already configured:
Then it’s simply a case of adding your stub mapping .json
files under mappings
as usual (see Stubbing).
Running as a browser proxy
WireMock can be made to work as a forward (browser) proxy.
One benefit of this is that it supports a website-based variant of the proxy/intercept pattern described above, allowing you to modify specific AJAX requests or swap out CSS/Javascript files.
To configure your browser to proxy via WireMock, first start WireMock with browser proxying enabled:
$ java -jar wiremock-standalone-2.19.0.jar --enable-browser-proxying --port 9999
Then open your browser’s proxy settings and point them to the running server:
After that, you can configure stubs as described in Running Standalone and then browse to a website. Any resources fetched whose requests are matched by stubs you have configured will be overridden by the stub’s response.
So for instance, say you’re visiting
a web page that fetches a user profile via an AJAX call to /users/12345.json
and you wanted to test how it responded to a server unavailable response. You could create a stub like this and the response from the server would be swapped for a 503 response:
stubFor(get(urlEqualTo("/users/12345.json"))
.willReturn(aResponse()
.withStatus(503)));
Proxying via another proxy server
If you’re inside a network that only permits HTTP traffic out to the
internet via an opaque proxy you might wish to set up proxy mappings
that route via this server. This can be configured programmatically by
passing a configuration object to the constructor of WireMockServer
or
the JUnit rules like this:
WireMockServer wireMockServer = new WireMockServer(options()
.proxyVia("proxy.mycorp.com", 8080)
);
Proxying to a target server that requires client certificate authentication
WireMock’s proxy client will send a client certificate if the target service requires it and a trust store containing the certificate is configured:
@Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig()
.trustStorePath("/path/to/truststore.jks")
.trustStorePassword("mostsecret")); // Defaults to "password" if omitted
See Running as a Standalone Process for command line equivalent.