Add support for automatically registering stubs in @AutoConfigureWireMock

This commit is contained in:
Dave Syer
2016-07-26 12:28:18 +01:00
parent 4305f40fd9
commit eb691717a2
11 changed files with 126 additions and 43 deletions

View File

@@ -57,6 +57,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<!-- tag::contract_bom[] -->
<dependencyManagement>

View File

@@ -1,5 +1,6 @@
package com.example.loan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -15,6 +16,7 @@ import com.example.loan.model.LoanApplicationResult;
import com.example.loan.model.LoanApplicationStatus;
@Service
@ConfigurationProperties("service")
public class LoanApplicationService {
private static final String FRAUD_SERVICE_JSON_VERSION_1 =

View File

@@ -22,12 +22,12 @@ import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWireMock
@SpringBootTest(properties="service.port=${wiremock.server.port}")
@AutoConfigureWireMock(port=0)
public class LoanApplicationServiceTests {
@Autowired
private LoanApplicationService sut;
private LoanApplicationService service;
@Value("classpath:META-INF/com.example/http-server-restdocs/0.0.1-SNAPSHOT/mappings/markClientAsFraud.json")
private Resource markClientAsFraud;
@@ -46,7 +46,7 @@ public class LoanApplicationServiceTests {
LoanApplication application = new LoanApplication(new Client("1234567890"),
123.123);
// when:
LoanApplicationResult loanApplication = sut.loanApplication(application);
LoanApplicationResult loanApplication = service.loanApplication(application);
// then:
assertThat(loanApplication.getLoanApplicationStatus())
.isEqualTo(LoanApplicationStatus.LOAN_APPLIED);
@@ -61,7 +61,7 @@ public class LoanApplicationServiceTests {
LoanApplication application = new LoanApplication(new Client("1234567890"),
99999);
// when:
LoanApplicationResult loanApplication = sut.loanApplication(application);
LoanApplicationResult loanApplication = service.loanApplication(application);
// then:
assertThat(loanApplication.getLoanApplicationStatus())
.isEqualTo(LoanApplicationStatus.LOAN_APPLICATION_REJECTED);

View File

@@ -1,3 +0,0 @@
stubrunner.stubs:
ids: 'com.example:http-server:+:stubs:8080'
repositoryRoot: http://repo.spring.io/libs-snapshot

View File

@@ -1,3 +0,0 @@
stubrunner:
work-offline: true
stubs.ids: 'com.example:http-server:+:stubs:8080'

View File

@@ -59,5 +59,10 @@
<artifactId>assertj-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -39,5 +39,7 @@ public @interface AutoConfigureWireMock {
int port() default 8080;
int httpsPort() default -1;
String stubs() default "";
}

View File

@@ -16,27 +16,35 @@
package org.springframework.cloud.contract.wiremock;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
/**
* @author Dave Syer
*
*/
@Configuration
public class WireMockConfiguration implements SmartLifecycle, ImportAware {
@EnableConfigurationProperties(WireMockProperties.class)
public class WireMockConfiguration implements SmartLifecycle {
private volatile boolean running;
@@ -45,47 +53,53 @@ public class WireMockConfiguration implements SmartLifecycle, ImportAware {
@Autowired(required = false)
private Options options;
@Value("${wiremock.server.port:8080}")
private int port = 8080;
@Value("${wiremock.server.https-port:-1}")
private int httpsPort = -1;
@Autowired
private DefaultListableBeanFactory beanFactory;
@Override
public void setImportMetadata(AnnotationMetadata metadata) {
AnnotationAttributes map = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(AutoConfigureWireMock.class.getName()));
int port = map.getNumber("port").intValue();
if (port > 0) {
this.port = port;
}
int httpsPort = map.getNumber("httpsPort").intValue();
if (httpsPort > 0) {
this.httpsPort = httpsPort;
}
}
@Autowired
private WireMockProperties wireMock;
@Autowired
private ResourceLoader resourceLoader;
@PostConstruct
public void init() {
public void init() throws IOException {
if (options == null) {
com.github.tomakehurst.wiremock.core.WireMockConfiguration factory = WireMockSpring.options();
if (port != 8080) {
factory.port(port);
com.github.tomakehurst.wiremock.core.WireMockConfiguration factory = WireMockSpring
.options();
if (wireMock.getPort() != 8080) {
factory.port(wireMock.getPort());
}
if (httpsPort != -1) {
factory.httpsPort(httpsPort);
if (wireMock.getHttpsPort() != -1) {
factory.httpsPort(wireMock.getHttpsPort());
}
this.options = factory;
}
server = new WireMockServer(options);
registerStubs();
if (!beanFactory.containsBean("wireMockServer")) {
beanFactory.registerSingleton("wireMockServer", server);
}
}
private void registerStubs() throws IOException {
if (StringUtils.hasText(wireMock.getStubs())) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
resourceLoader);
String pattern = wireMock.getStubs();
if (!pattern.contains("*")) {
if (!pattern.endsWith("/")) {
pattern = pattern + "/";
}
pattern = pattern + "**/*.json";
}
for (Resource resource : resolver.getResources(pattern)) {
server.addStubMapping(StubMapping.buildFrom(StreamUtils.copyToString(
resource.getInputStream(), Charset.forName("UTF-8"))));
}
}
}
@Override
public void start() {
server.start();
@@ -123,3 +137,37 @@ public class WireMockConfiguration implements SmartLifecycle, ImportAware {
}
}
@ConfigurationProperties("wiremock.server")
class WireMockProperties {
private int port = 8080;
private int httpsPort = -1;
private String stubs;
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getHttpsPort() {
return httpsPort;
}
public void setHttpsPort(int httpsPort) {
this.httpsPort = httpsPort;
}
public String getStubs() {
return stubs;
}
public void setStubs(String stubs) {
this.stubs = stubs;
}
}

View File

@@ -40,7 +40,7 @@ public class WireMockExpectations {
private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
private String prefix = "classpath:/stubs/";
private String prefix = "classpath:/mappings/";
private String suffix = ".json";

View File

@@ -0,0 +1,27 @@
package org.springframework.cloud.contract.wiremock;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=WiremockTestsApplication.class, properties="app.baseUrl=http://localhost:${wiremock.server.port}", webEnvironment=WebEnvironment.NONE)
@DirtiesContext
@AutoConfigureWireMock(port=0, stubs="file:src/test/resources/mappings")
public class AutoConfigureWireMockStubsApplicationTests {
@Autowired
private Service service;
@Test
public void contextLoads() throws Exception {
assertThat(this.service.go()).isEqualTo("Hello World");
}
}