Skip to content

Commit 54d0191

Browse files
Add option to customize configuration on @ConfigureWireMock annotation (#18)
Fixes #16
1 parent 4fd8a99 commit 54d0191

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,33 @@ It can be changed with setting `stubLocation` on `@ConfigureWireMock`:
7070
@ConfigureWireMock(name = "...", property = "...", stubLocation = "my-stubs")
7171
```
7272

73+
### Advanced configuration
74+
75+
More advanced configuration can be applied through configuration customizers:
76+
77+
```java
78+
@ConfigureWireMock(
79+
name = "todo-service",
80+
property = "todo-service.url",
81+
configurationCustomizers = SampleConfigurationCustomizer.class
82+
)
83+
```
84+
85+
Where `SampleConfigurationCustomizer` is a class implementing `WireMockConfigurationCustomizer`:
86+
87+
```java
88+
class SampleConfigurationCustomizer implements WireMockConfigurationCustomizer {
89+
90+
@Override
91+
public void customize(WireMockConfiguration configuration, ConfigureWireMock options) {
92+
// apply changes to configuration
93+
}
94+
}
95+
```
96+
97+
> [!IMPORTANT]
98+
> `WireMockConfigurationCustomizer` must have a no-arg constructor.
99+
73100
Sounds good? Consider [❤️ Sponsoring](https://github.com/sponsors/maciejwalkowiak) the project! Thank you!
74101

75102
## 🙏 Credits

wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/ConfigureWireMock.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.lang.annotation.RetentionPolicy;
55

66
import com.github.tomakehurst.wiremock.WireMockServer;
7+
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
78
import com.github.tomakehurst.wiremock.extension.Extension;
89

910
/**
@@ -50,4 +51,11 @@
5051
* @return the extensions
5152
*/
5253
Class<? extends Extension>[] extensions() default {};
54+
55+
/**
56+
* Customizes {@link WireMockConfiguration} used by {@link WireMockServer} instance. Customizers are ordered by their natural order in this array. Each customizer must have no-arg constructor.
57+
*
58+
* @return the configuration customizers classes
59+
*/
60+
Class<? extends WireMockConfigurationCustomizer>[] configurationCustomizers() default {};
5361
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.maciejwalkowiak.wiremock.spring;
2+
3+
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
4+
5+
/**
6+
* Customizes {@link WireMockConfiguration} programmatically. Can be registered with {@link ConfigureWireMock#configurationCustomizers()}.
7+
* Customizer must have public no-arg constructor.
8+
*/
9+
public interface WireMockConfigurationCustomizer {
10+
11+
void customize(WireMockConfiguration configuration, ConfigureWireMock options);
12+
}

wiremock-spring-boot/src/main/java/com/maciejwalkowiak/wiremock/spring/WireMockContextCustomizer.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import com.github.tomakehurst.wiremock.WireMockServer;
88
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
9+
import org.junit.platform.commons.util.ReflectionUtils;
910
import org.junit.platform.commons.util.StringUtils;
1011
import org.slf4j.Logger;
1112
import org.slf4j.LoggerFactory;
@@ -56,8 +57,6 @@ public void customizeContext(ConfigurableApplicationContext context, MergedConte
5657
}
5758

5859
private void resolveOrCreateWireMockServer(ConfigurableApplicationContext context, ConfigureWireMock options) {
59-
LOGGER.info("Configuring WireMockServer with name '{}' on port: {}", options.name(), options.port());
60-
6160
WireMockServer wireMockServer = Store.INSTANCE.findWireMockInstance(context, options.name());
6261

6362
if (wireMockServer == null) {
@@ -70,6 +69,10 @@ private void resolveOrCreateWireMockServer(ConfigurableApplicationContext contex
7069
serverOptions.extensions(options.extensions());
7170
}
7271

72+
applyCustomizers(options, serverOptions);
73+
74+
LOGGER.info("Configuring WireMockServer with name '{}' on port: {}", options.name(), serverOptions.portNumber());
75+
7376
WireMockServer newServer = new WireMockServer(serverOptions);
7477
newServer.start();
7578

@@ -95,6 +98,19 @@ private void resolveOrCreateWireMockServer(ConfigurableApplicationContext contex
9598
}
9699
}
97100

101+
private static void applyCustomizers(ConfigureWireMock options, WireMockConfiguration serverOptions) {
102+
for (Class<? extends WireMockConfigurationCustomizer> customizer : options.configurationCustomizers()) {
103+
try {
104+
ReflectionUtils.newInstance(customizer).customize(serverOptions, options);
105+
} catch (Exception e) {
106+
if (e instanceof NoSuchMethodException) {
107+
LOGGER.error("Customizer {} must have a no-arg constructor", customizer, e);
108+
}
109+
throw e;
110+
}
111+
}
112+
}
113+
98114
private String resolveStubLocation(ConfigureWireMock options) {
99115
return StringUtils.isBlank(options.stubLocation()) ? "wiremock/" + options.name() : options.stubLocation();
100116
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.maciejwalkowiak.wiremock.spring;
2+
3+
import com.github.tomakehurst.wiremock.WireMockServer;
4+
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
5+
import org.junit.jupiter.api.Test;
6+
7+
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
import org.springframework.test.util.TestSocketUtils;
10+
11+
import static org.assertj.core.api.Assertions.assertThat;
12+
13+
@SpringBootTest(classes = WireMockConfigurationCustomizerTest.AppConfiguration.class)
14+
@EnableWireMock({
15+
@ConfigureWireMock(
16+
name = "user-service",
17+
property = "user-service.url",
18+
configurationCustomizers = WireMockConfigurationCustomizerTest.SampleConfigurationCustomizer.class
19+
),
20+
@ConfigureWireMock(
21+
name = "todo-service",
22+
property = "todo-service.url",
23+
configurationCustomizers = WireMockConfigurationCustomizerTest.SampleConfigurationCustomizer.class
24+
),
25+
})
26+
class WireMockConfigurationCustomizerTest {
27+
private static final int USER_SERVICE_PORT = TestSocketUtils.findAvailableTcpPort();
28+
private static final int TODO_SERVICE_PORT = TestSocketUtils.findAvailableTcpPort();
29+
30+
static class SampleConfigurationCustomizer implements WireMockConfigurationCustomizer {
31+
32+
@Override
33+
public void customize(WireMockConfiguration configuration, ConfigureWireMock options) {
34+
if (options.name().equals("user-service")) {
35+
configuration.port(USER_SERVICE_PORT);
36+
} else {
37+
configuration.port(TODO_SERVICE_PORT);
38+
}
39+
}
40+
}
41+
42+
@SpringBootApplication
43+
static class AppConfiguration {
44+
45+
}
46+
47+
@InjectWireMock("user-service")
48+
private WireMockServer userService;
49+
50+
@InjectWireMock("todo-service")
51+
private WireMockServer todoService;
52+
53+
@Test
54+
void appliesConfigurationCustomizer() {
55+
assertThat(userService.port()).isEqualTo(USER_SERVICE_PORT);
56+
assertThat(todoService.port()).isEqualTo(TODO_SERVICE_PORT);
57+
}
58+
59+
}

0 commit comments

Comments
 (0)