[[features-wiremock]]
== Spring Cloud Contract WireMock
include::_attributes.adoc[]

The Spring Cloud Contract WireMock modules let you use https://github.com/tomakehurst/wiremock[WireMock] in a
Spring Boot application. For more detail, check out the
https://github.com/spring-cloud/spring-cloud-contract/tree/{github-tag}/samples[samples].

If you have a Spring Boot application that uses Tomcat as an embedded server (which is
the default with `spring-boot-starter-web`), you can add
`spring-cloud-starter-contract-stub-runner` to your classpath and add `@AutoConfigureWireMock`
to use Wiremock in your tests. Wiremock runs as a stub server, and you
can register stub behavior by using a Java API or by using static JSON declarations as part of
your test. The following code shows an example:

====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test1]
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsTests.java[tags=wiremock_test2]
----
====

To start the stub server on a different port, use (for example),
`@AutoConfigureWireMock(port=9999)`. For a random port, use a value of `0`. The stub
server port can be bound in the test application context with the `wiremock.server.port`
property. Using `@AutoConfigureWireMock` adds a bean of type `WiremockConfiguration` to
your test application context, where it is cached between methods and classes
that have the same context. The same is true for Spring integration tests. Also, you can
inject a bean of type `WireMockServer` into your test.
The registered WireMock server is reset after each test class.
However, if you need to reset it after each test method, set the `wiremock.reset-mappings-after-each-test` property to `true`.

[[features-wiremock-registering-stubs]]
=== Registering Stubs Automatically

If you use `@AutoConfigureWireMock`, it registers WireMock JSON stubs from the file
system or classpath (by default, from `file:src/test/resources/mappings`). You can
customize the locations by using the `stubs` attribute in the annotation, which can be an
Ant-style resource pattern or a directory. In the case of a directory, `**/*.json` is
appended. The following code shows an example:

====
----
@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!");
	}

}
----
====

NOTE: Actually, WireMock always loads mappings from `src/test/resources/mappings` *as
well as* the custom locations in the `stubs` attribute. To change this behavior, you can
also specify a file root, as described in the <<features-wiremock-using-files,next section of this document>>.

NOTE: Also, the mappings in the `stubs` location are not considered part of Wiremock's "default mappings" and calls
to `com.github.tomakehurst.wiremock.client.WireMock.resetToDefaultMappings` during a test do not result in the mappings
in the `stubs` location being included. However, the `org.springframework.cloud.contract.wiremock.WireMockTestExecutionListener`
does reset the mappings (including adding the ones from the stubs location) after every test class and, optionally,
after every test method (guarded by the `wiremock.reset-mappings-after-each-test` property).

If you use Spring Cloud Contract's default stub jars, your
stubs are stored in the `/META-INF/group-id/artifact-id/versions/mappings/` folder.
If you want to register all stubs from that location, from all embedded JARs, you can use
the following syntax:

====
[source,java,indent=0]
----
include::{wiremock_tests}/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java[tags=load_all_stubs]
----
====

[[features-wiremock-using-files]]
=== Using Files to Specify the Stub Bodies

WireMock can read response bodies from files on the classpath or the file system. In the
case of the file system, you can see in the JSON DSL that the response has a `bodyFileName` instead of a
(literal) `body`. The files are resolved relative to a root directory (by default,
`src/test/resources/\__files`). To customize this location, you can set the `files`
attribute in the `@AutoConfigureWireMock` annotation to the location of the parent
directory (in other words, `__files` is a subdirectory). You can use a Spring resource
notation to refer to `file:...` or `classpath:...` locations. Generic URLs are not
supported. A list of values can be given -- in which case, WireMock resolves the first file
that exists when it needs to find a response body.

NOTE: When you configure the `files` root, it also affects the
automatic loading of stubs, because they come from the root location
in a subdirectory called `mappings`.

NOTE: The value of `files` has no
effect on the stubs loaded explicitly from the `stubs` attribute.

[[features-wiremock-junit-rule]]
=== Alternative: Using JUnit Rules

For a more conventional WireMock experience, you can use JUnit `@Rules` to start and stop
the server. To do so, use the `WireMockSpring` convenience class to obtain an `Options`
instance, as the following example shows:

====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test1]
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsClassRuleTests.java[tags=wiremock_test2]
----
====

The `@ClassRule` means that the server shuts down after all the methods in this class
have been run.

[[features-wiremock-relaxed-ssl]]
=== Relaxed SSL Validation for Rest Template

WireMock lets you stub a "`secure`" server with an `https` URL protocol. If your
application wants to contact that stub server in an integration test, it finds that
the SSL certificates are not valid (the usual problem with self-installed certificates).
The best option is often to re-configure the client to use `http`. If that is not an
option, you can ask Spring to configure an HTTP client that ignores SSL validation errors
(do so only for tests, of course).

To make this work with minimum fuss, you need to use the Spring Boot
`RestTemplateBuilder` in your application, as the following example shows:

====
[source,java,indent=0]
----
	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}
----
====

You need `RestTemplateBuilder` because the builder is passed through callbacks to
initialize it, so the SSL validation can be set up in the client at that point. This
happens automatically in your test if you use the `@AutoConfigureWireMock`
annotation or the stub runner. If you use the JUnit `@Rule` approach, you need to add the
`@AutoConfigureHttpClient` annotation as well, as the following example shows:

====
[source,java,indent=0]
----
@RunWith(SpringRunner.class)
@SpringBootTest("app.baseUrl=https://localhost:6443")
@AutoConfigureHttpClient
public class WiremockHttpsServerApplicationTests {

	@ClassRule
	public static WireMockClassRule wiremock = new WireMockClassRule(
			WireMockSpring.options().httpsPort(6443));
...
}
----
====

If you use `spring-boot-starter-test`, you have the Apache HTTP client on the
classpath, and it is selected by the `RestTemplateBuilder` and configured to ignore SSL
errors. If you use the default `java.net` client, you do not need the annotation (but it
does no harm). There is currently no support for other clients, but it may be added
in future releases.

To disable the custom `RestTemplateBuilder`, set the `wiremock.rest-template-ssl-enabled`
property to `false`.

[[features-wiremock-spring-mvc-mocks]]
=== WireMock and Spring MVC Mocks

Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into
a Spring `MockRestServiceServer`. The following code shows an example:

====
[source,java,indent=0]
----
include::{doc_samples_url}/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java[tags=wiremock_test]
----
====

The `baseUrl` value is prepended to all mock calls, and the `stubs()` method takes a stub
path resource pattern as an argument. In the preceding example, the stub defined at
`/stubs/resource.json` is loaded into the mock server. If the `RestTemplate` is asked to
visit `https://example.org/`, it gets the responses as being declared at that URL. More
than one stub pattern can be specified, and each one can be a directory (for a recursive
list of all `.json`), a fixed filename (as in the preceding example), or an Ant-style
pattern. The JSON format is the normal WireMock format, which you can read about at the
https://wiremock.org/docs/stubbing/[WireMock website].

Currently, the Spring Cloud Contract Verifier supports Tomcat, Jetty, and Undertow as
Spring Boot embedded servers, and Wiremock itself has "`native`" support for a particular
version of Jetty (currently 9.2). To use the native Jetty, you need to add the native
Wiremock dependencies and exclude the Spring Boot container (if there is one).
