3. Using the Stubs

The Initializr project publishes WireMock stubs for all the JSON responses that are tested in the project. If you are writing a client for the Initializr service, you can use these stubs to test your own code. You can consume them with the raw Wiremock APIs, or via some features of Spring Cloud Contract.

WireMock is an embedded web server that analyses incoming requests and chooses stub responses based on matching some rules (e.g. a specific header value). So if you send it a request which matches one of its stubs, it will send you a response as if it was a real Initializr service, and you can use that to do full stack integration testing of your client.

3.1 Using WireMock with Spring Boot

A convenient way to consume the stubs in your project is to add a test dependency:

<dependency>
    <groupId>io.spring.initializr</groupId>
    <artifactId>initializr-web</artifactId>
    <classifier>stubs</classifier>
    <version>{project-version}</version>
    <scope>test</scope>
</dependency>

and then pull the stubs from the classpath. In a Spring Boot application, using Spring Cloud Contract, you can start a WireMock server and register all the stubs with it like this:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWireMock(port = 0,
    stubs="classpath:META-INF/io.spring.initializr/initializr-web/0.3.0.BUILD-SNAPSHOT")
public class ClientApplicationTests {

	@Value("${wiremock.server.port}")
	private int port;

    ...

}

Alternatively you can configure the stub runner to look for the artifact. The example below will automatically download, if necessary, the latest version of the initializr stubs:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
@AutoConfigureStubRunner(
		ids = "io.spring.initializr:initializr-web",
		workOffline = true)
public class InitializrIntegrationTests {

	@Autowired
	private StubFinder stubFinder;

	@Autowired
	private RestTemplate restTemplate;

	@Test
	public void testCurrentMetadata() throws IOException {
		RequestEntity<Void> request = RequestEntity.get(createUri("/"))
				.accept(MediaType.valueOf("application/vnd.initializr.v2.1+json"))
				.build();

		ResponseEntity<String> response = this.restTemplate
				.exchange(request, String.class);
		assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
		// other assertions here
	}

	private URI createUri(String path) {
		String url = this.stubFinder.findStubUrl("initializr-web").toString();
		return URI.create(url + path);
	}

	@TestConfiguration
	static class Config {

		@Bean
		public RestTemplate restTemplate(RestTemplateBuilder builder) {
			return builder.build();
		}

	}

}
[Tip]Tip

If you want to test a specific version or validate your API against multiple versions you can define the version to use in the annotation, something like

@AutoConfigureStubRunner(
        ids = "io.spring.initializr:initializr-web:0.3.0.BUILD-SNAPSHOT",
        workOffline = true)
public class InitializrIntegrationTests {
    ...
}

Then you have a server that returns the stub of the JSON metadata (metadataWithCurrentAcceptHeader.json) when you send it a header Accept:application/vnd.initializr.v2.1+json (as recommended).

3.2 Names and Paths of Stubs

The stubs are laid out in a jar file in a form (under "/mappings") that can be consumed by WireMock just by setting its file source. The names of the individual stubs are the same as the method names of the test cases that generated them in the Initializr project. So for example there is a test case "metadataWithV2AcceptHeader" in MainControllerIntegrationTests that makes assertions about the response when the accept header is application/vnd.initializr.v2.1+json. The response is recorded in the stub, and it will match in WireMock if the same headers and request parameters that were used in the Initializr test case and used in the client. The method name usually summarizes what those values are.