diff --git a/README.md b/README.md
index ed7a927..36d7c52 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,58 @@ WireMock extensions can be registered independently with each `@ConfigureWireMoc
@ConfigureWireMock(name = "...", property = "...", extensions = { ... })
```
+### Single vs Multiple Property Injection
+
+The concept of single property injection can be described as wiring _one_ `WireMockServer` instance to _one_ property.
+
+```java
+@SpringBootTest
+@EnableWireMock({
+ @ConfigureWireMock(name = "foo-service", property = "app.client-apis.foo.base-path"}),
+ @ConfigureWireMock(name = "bar-service", property = "app.client-apis.bar.base-path"}),
+ @ConfigureWireMock(name = "mojo-service", property = "app.client-apis.mojo.base-path"})
+})
+class AppIT {
+ @InjectWireMock("foo-service")
+ private WireMockServer fooService;
+ @InjectWireMock("bar-service")
+ private WireMockServer barService;
+ @InjectWireMock("mojo-service")
+ private WireMockServer mojoService;
+
+ @Test
+ void contextLoads() {
+ // your test code
+ }
+}
+```
+
+The concept of multiple property injection can be described as wiring _one_ `WireMockServer` instance to _multiple_ properties.
+
+```java
+@SpringBootTest
+@EnableWireMock({
+ @ConfigureWireMock(name = "services", properties = {
+ "app.client-apis.foo.base-path",
+ "app.client-apis.bar.base-path",
+ "app.client-apis.mojo.base-path"})
+})
+class AppIT {
+
+ @InjectWireMock("services")
+ private WireMockServer services;
+
+ @Test
+ void contextLoads() {
+ // your test code
+ }
+}
+```
+
+The *single* property injection provides a high level of isolation when mocking and stubbing 3rd pary RESTful api, because every service
+is associated to its own dedicated `WireMockServer` instance.
+The *multiple* property injections provides a less complex test setup at the cost of isolation.
+
### Customizing mappings directory
By default, each `WireMockServer` is configured to load mapping files from a classpath directory `wiremock/{server-name}/mappings`.
diff --git a/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/ConfigureWireMock.java b/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/ConfigureWireMock.java
index 723d38b..4a22b02 100644
--- a/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/ConfigureWireMock.java
+++ b/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/ConfigureWireMock.java
@@ -32,10 +32,18 @@
/**
* The name of Spring property to inject the {@link WireMockServer#baseUrl()}
*
+ * @deprecated please use {@link ConfigureWireMock#properties()}
* @return the name of Spring property to inject the {@link WireMockServer#baseUrl()}
*/
+ @Deprecated(since = "2.1.3")
String property() default "";
+ /**
+ * Names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
+ *
+ * @return names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
+ */
+ String[] properties() default {};
/**
* The location of WireMock stub files. By default, stubs are resolved from classpath location wiremock-server-name/mappings/
.
*
diff --git a/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/WireMockContextCustomizer.java b/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/WireMockContextCustomizer.java
index 94ddcb2..e7e62be 100644
--- a/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/WireMockContextCustomizer.java
+++ b/wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/WireMockContextCustomizer.java
@@ -7,6 +7,7 @@
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.common.Notifier;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import java.util.stream.Collectors;
import org.junit.platform.commons.util.ReflectionUtils;
import org.junit.platform.commons.util.StringUtils;
import org.slf4j.Logger;
@@ -91,11 +92,19 @@ private void resolveOrCreateWireMockServer(ConfigurableApplicationContext contex
});
// configure Spring environment property
+ List propertyNames;
if (StringUtils.isNotBlank(options.property())) {
- String property = options.property() + "=" + newServer.baseUrl();
+ propertyNames = List.of(options.property());
+ } else {
+ propertyNames = Arrays.stream(options.properties())
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toList());
+ }
+ propertyNames.forEach(propertyName -> {
+ String property = propertyName + "=" + newServer.baseUrl();
LOGGER.debug("Adding property '{}' to Spring application context", property);
TestPropertyValues.of(property).applyTo(context.getEnvironment());
- }
+ });
} else {
LOGGER.info("WireMockServer with name '{}' is already configured", options.name());
}
diff --git a/wiremock-spring-boot/src/test/java/app/WireMockSpringExtensionTest.java b/wiremock-spring-boot/src/test/java/app/WireMockSpringExtensionTest.java
index 8a11925..0a13647 100644
--- a/wiremock-spring-boot/src/test/java/app/WireMockSpringExtensionTest.java
+++ b/wiremock-spring-boot/src/test/java/app/WireMockSpringExtensionTest.java
@@ -4,6 +4,7 @@
import com.maciejwalkowiak.wiremock.spring.ConfigureWireMock;
import com.maciejwalkowiak.wiremock.spring.EnableWireMock;
import com.maciejwalkowiak.wiremock.spring.InjectWireMock;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,54 +14,85 @@
import static org.assertj.core.api.Assertions.assertThat;
-@SpringBootTest(classes = WireMockSpringExtensionTest.AppConfiguration.class)
-@EnableWireMock({
- @ConfigureWireMock(name = "user-service", property = "user-service.url"),
- @ConfigureWireMock(name = "todo-service", property = "todo-service.url"),
- @ConfigureWireMock(name = "noproperty-service")
-})
public class WireMockSpringExtensionTest {
- @SpringBootApplication
- static class AppConfiguration {
+ @SpringBootTest(classes = WireMockSpringExtensionTest.AppConfiguration.class)
+ @EnableWireMock({
+ @ConfigureWireMock(name = "user-service", property = "user-service.url"),
+ @ConfigureWireMock(name = "todo-service", property = "todo-service.url"),
+ @ConfigureWireMock(name = "noproperty-service")
+ })
+ @Nested
+ class SinglePropertyBindingTest {
- }
+ @InjectWireMock("todo-service")
+ private WireMockServer todoWireMockServer;
- @InjectWireMock("todo-service")
- private WireMockServer todoWireMockServer;
+ @Autowired
+ private Environment environment;
- @Autowired
- private Environment environment;
+ @Test
+ void createsWiremockWithClassLevelConfigureWiremock(@InjectWireMock("user-service") WireMockServer wireMockServer) {
+ assertWireMockServer(wireMockServer, "user-service.url");
+ }
- @Test
- void createsWiremockWithClassLevelConfigureWiremock(@InjectWireMock("user-service") WireMockServer wireMockServer) {
- assertWireMockServer(wireMockServer, "user-service.url");
- }
+ @Test
+ void createsWiremockWithFieldLevelConfigureWiremock() {
+ assertWireMockServer(todoWireMockServer, "todo-service.url");
+ }
+
+ @Test
+ void doesNotSetPropertyWhenNotProvided(@InjectWireMock("noproperty-service") WireMockServer wireMockServer) {
+ assertThat(wireMockServer)
+ .as("inject wiremock sets null when not configured")
+ .isNotNull();
+ }
- @Test
- void createsWiremockWithFieldLevelConfigureWiremock() {
- assertWireMockServer(todoWireMockServer, "todo-service.url");
+ private void assertWireMockServer(WireMockServer wireMockServer, String property) {
+ assertThat(wireMockServer)
+ .as("creates WireMock instance")
+ .isNotNull();
+ assertThat(wireMockServer.baseUrl())
+ .as("WireMock baseUrl is set")
+ .isNotNull();
+ assertThat(wireMockServer.port())
+ .as("sets random port")
+ .isNotZero();
+ assertThat(environment.getProperty(property))
+ .as("sets Spring property")
+ .isEqualTo(wireMockServer.baseUrl());
+ }
}
- @Test
- void doesNotSetPropertyWhenNotProvided(@InjectWireMock("noproperty-service") WireMockServer wireMockServer) {
- assertThat(wireMockServer)
- .as("creates WireMock instance")
- .isNotNull();
+ @SpringBootTest(classes = WireMockSpringExtensionTest.AppConfiguration.class)
+ @EnableWireMock({
+ @ConfigureWireMock(name = "user-service", properties = {"user-service.url", "todo-service.url"}),
+ @ConfigureWireMock(name = "mojo-service", property = "mojo-service.url", properties = {"other-service.url"})
+ })
+ @Nested
+ class MultiplePropertiesBindingTest {
+
+ @InjectWireMock("user-service")
+ private WireMockServer userServiceWireMockServer;
+
+ @InjectWireMock("mojo-service")
+ private WireMockServer mojoServiceWireMockServer;
+
+ @Autowired
+ private Environment environment;
+
+ @Test
+ void bindsUrlToMultipleProperties() {
+ assertThat(environment.getProperty("user-service.url")).isEqualTo(userServiceWireMockServer.baseUrl());
+ assertThat(environment.getProperty("todo-service.url")).isEqualTo(userServiceWireMockServer.baseUrl());
+ // single property binding takes precedence over multiple properties binding
+ assertThat(environment.getProperty("mojo-service.url")).isEqualTo(mojoServiceWireMockServer.baseUrl());
+ assertThat(environment.getProperty("other-service.url")).isNull();
+ }
}
- private void assertWireMockServer(WireMockServer wireMockServer, String property) {
- assertThat(wireMockServer)
- .as("creates WireMock instance")
- .isNotNull();
- assertThat(wireMockServer.baseUrl())
- .as("WireMock baseUrl is set")
- .isNotNull();
- assertThat(wireMockServer.port())
- .as("sets random port")
- .isNotZero();
- assertThat(environment.getProperty(property))
- .as("sets Spring property")
- .isEqualTo(wireMockServer.baseUrl());
+ @SpringBootApplication
+ static class AppConfiguration {
+
}
}