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