Spring Cloud Contract WireMock

The Spring Cloud Contract WireMock modules let you use WireMock in a Spring Boot application. For more detail, check out the Spring Cloud Contract’s repository samples subfolder.

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.

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.

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

}
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 next section of this document.
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:

@AutoConfigureWireMock(port = 0, stubs = "classpath*:/META-INF...

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.

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.
The value of files has no effect on the stubs loaded explicitly from the stubs attribute.

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:

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

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:

@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:

@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.

WireMock and Spring MVC Mocks

Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into a Spring MockRestServiceServer. The following project shows that.

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 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 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).