Skip to content

Commit 35f7867

Browse files
authored
Merge pull request #56 from wiremock/feature/configure-wiremock-for-correct
fix: wiremock default port was not always configured
2 parents 99c2fde + 14b3f3f commit 35f7867

File tree

7 files changed

+163
-20
lines changed

7 files changed

+163
-20
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ allprojects {
2626
testImplementation platform('org.junit:junit-bom:5.11.2')
2727
testImplementation 'org.junit.jupiter:junit-jupiter'
2828
testImplementation 'org.junit.platform:junit-platform-launcher'
29+
testImplementation 'io.rest-assured:rest-assured:5.5.0'
2930

3031
constraints {
3132
implementation('org.apache.commons:commons-compress:1.26.0') {
@@ -58,6 +59,5 @@ project('wiremock-spring-boot-example', {
5859
implementation "org.springframework.boot:spring-boot-starter-webflux:3.3.4"
5960

6061
testImplementation rootProject
61-
testImplementation 'io.rest-assured:rest-assured:5.5.0'
6262
}
6363
})

src/main/java/org/wiremock/spring/EnableWireMock.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414
@Target({ElementType.TYPE})
1515
@Retention(RetentionPolicy.RUNTIME)
16-
@ExtendWith(org.wiremock.spring.internal.WireMockSpringExtension.class)
16+
@ExtendWith(org.wiremock.spring.internal.WireMockSpringJunitExtension.class)
1717
public @interface EnableWireMock {
1818
/**
1919
* A list of {@link com.github.tomakehurst.wiremock.WireMockServer} configurations. For each

src/main/java/org/wiremock/spring/internal/WireMockContextCustomizer.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.wiremock.spring.internal;
22

33
import com.github.tomakehurst.wiremock.WireMockServer;
4-
import com.github.tomakehurst.wiremock.client.WireMock;
54
import java.util.Arrays;
65
import java.util.List;
76
import java.util.Objects;
@@ -45,11 +44,7 @@ public WireMockContextCustomizer(final ConfigureWireMock... configurations) {
4544
public void customizeContext(
4645
final ConfigurableApplicationContext context, final MergedContextConfiguration mergedConfig) {
4746
for (final ConfigureWireMock configureWiremock : this.configuration) {
48-
final WireMockServer wireMockServer =
49-
this.resolveOrCreateWireMockServer(context, configureWiremock);
50-
if (this.configuration.size() == 1) {
51-
WireMock.configureFor(wireMockServer.port());
52-
}
47+
this.resolveOrCreateWireMockServer(context, configureWiremock);
5348
}
5449
}
5550

@@ -67,6 +62,11 @@ private WireMockServer resolveOrCreateWireMockServer(
6762
return wireMockServer;
6863
}
6964

65+
/**
66+
* The docs in {@link ContextCustomizer} states that equals and hashcode is being used for caching
67+
* and needs implementation. The customizeContext method will not be invoked for all tests,
68+
* because of caching.
69+
*/
7070
@Override
7171
public boolean equals(final Object o) {
7272
if (this == o) {

src/main/java/org/wiremock/spring/internal/WireMockContextCustomizerFactory.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@
1717
* @author Maciej Walkowiak
1818
*/
1919
public class WireMockContextCustomizerFactory implements ContextCustomizerFactory {
20-
private static final ConfigureWireMock DEFAULT_CONFIGURE_WIREMOCK =
20+
static final ConfigureWireMock DEFAULT_CONFIGURE_WIREMOCK =
2121
DefaultConfigureWireMock.class.getAnnotation(ConfigureWireMock.class);
2222

2323
@ConfigureWireMock(name = "wiremock")
2424
private static class DefaultConfigureWireMock {}
2525

26+
static ConfigureWireMock[] getConfigureWireMocksOrDefault(final ConfigureWireMock... value) {
27+
if (value == null || value.length == 0) {
28+
return new ConfigureWireMock[] {WireMockContextCustomizerFactory.DEFAULT_CONFIGURE_WIREMOCK};
29+
}
30+
return value;
31+
}
32+
2633
@Override
2734
public ContextCustomizer createContextCustomizer(
2835
final Class<?> testClass, final List<ContextConfigurationAttributes> configAttributes) {
@@ -54,12 +61,7 @@ void add(final ConfigureWireMock... annotations) {
5461
void parse(final Class<?> clazz) {
5562
final EnableWireMock annotation = AnnotationUtils.findAnnotation(clazz, EnableWireMock.class);
5663
if (annotation != null) {
57-
final ConfigureWireMock[] value = annotation.value();
58-
if (value.length == 0) {
59-
this.add(WireMockContextCustomizerFactory.DEFAULT_CONFIGURE_WIREMOCK);
60-
} else {
61-
this.add(value);
62-
}
64+
this.add(getConfigureWireMocksOrDefault(annotation.value()));
6365
}
6466
}
6567

src/main/java/org/wiremock/spring/internal/WireMockSpringExtension.java renamed to src/main/java/org/wiremock/spring/internal/WireMockSpringJunitExtension.java

+46-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
import org.junit.jupiter.api.extension.ParameterContext;
1313
import org.junit.jupiter.api.extension.ParameterResolver;
1414
import org.junit.platform.commons.support.AnnotationSupport;
15+
import org.slf4j.Logger;
16+
import org.slf4j.LoggerFactory;
17+
import org.springframework.core.annotation.AnnotationUtils;
18+
import org.wiremock.spring.ConfigureWireMock;
19+
import org.wiremock.spring.EnableWireMock;
1520
import org.wiremock.spring.InjectWireMock;
1621

1722
/**
@@ -20,8 +25,9 @@
2025
*
2126
* @author Maciej Walkowiak
2227
*/
23-
public class WireMockSpringExtension
28+
public class WireMockSpringJunitExtension
2429
implements BeforeEachCallback, AfterEachCallback, ParameterResolver {
30+
private static final Logger LOGGER = LoggerFactory.getLogger(WireMockSpringJunitExtension.class);
2531

2632
@Override
2733
public void beforeEach(final ExtensionContext extensionContext) throws Exception {
@@ -30,6 +36,45 @@ public void beforeEach(final ExtensionContext extensionContext) throws Exception
3036

3137
// inject properties into test class fields
3238
injectWireMockInstances(extensionContext, InjectWireMock.class, InjectWireMock::value);
39+
40+
this.configureWireMockForDefaultInstance(extensionContext);
41+
}
42+
43+
private void configureWireMockForDefaultInstance(final ExtensionContext extensionContext) {
44+
final List<Object> instances = extensionContext.getRequiredTestInstances().getAllInstances();
45+
WireMockServer wiremock = null;
46+
String wireMockName = null;
47+
for (final Object instance : instances) {
48+
final EnableWireMock enableWireMockAnnotation =
49+
AnnotationUtils.findAnnotation(instance.getClass(), EnableWireMock.class);
50+
if (enableWireMockAnnotation == null) {
51+
continue;
52+
}
53+
final ConfigureWireMock[] wireMockServers =
54+
WireMockContextCustomizerFactory.getConfigureWireMocksOrDefault(
55+
enableWireMockAnnotation.value());
56+
if (wireMockServers.length > 1) {
57+
LOGGER.info(
58+
"Not configuring WireMock for default instance when several ConfigureWireMock ("
59+
+ wireMockServers.length
60+
+ ")");
61+
}
62+
if (wiremock != null) {
63+
LOGGER.info("Not configuring WireMock for default instance when several candidates found");
64+
return;
65+
}
66+
wireMockName = wireMockServers[0].name();
67+
wiremock = Store.INSTANCE.findRequiredWireMockInstance(extensionContext, wireMockName);
68+
}
69+
if (wiremock != null) {
70+
LOGGER.info(
71+
"Configuring WireMock for default instance, '"
72+
+ wireMockName
73+
+ "' on '"
74+
+ wiremock.port()
75+
+ "'.");
76+
WireMock.configureFor(wiremock.port());
77+
}
3378
}
3479

3580
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package app;
2+
3+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
4+
import static com.github.tomakehurst.wiremock.client.WireMock.get;
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
import com.github.tomakehurst.wiremock.WireMockServer;
8+
import com.github.tomakehurst.wiremock.client.WireMock;
9+
import io.restassured.RestAssured;
10+
import org.junit.jupiter.api.DisplayName;
11+
import org.junit.jupiter.api.Nested;
12+
import org.junit.jupiter.api.Test;
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.boot.autoconfigure.SpringBootApplication;
15+
import org.springframework.boot.test.context.SpringBootTest;
16+
import org.springframework.core.env.Environment;
17+
import org.wiremock.spring.ConfigureWireMock;
18+
import org.wiremock.spring.EnableWireMock;
19+
import org.wiremock.spring.InjectWireMock;
20+
21+
@SpringBootTest(classes = NestedClassSingleWireMockTest.AppConfiguration.class)
22+
@EnableWireMock({
23+
@ConfigureWireMock(
24+
name = "todo-service",
25+
baseUrlProperties = "todo-service.url",
26+
portProperties = "todo-service.port")
27+
})
28+
public class NestedClassSingleWireMockTest {
29+
30+
@SpringBootApplication
31+
static class AppConfiguration {}
32+
33+
@Autowired private Environment environment;
34+
35+
@InjectWireMock("todo-service")
36+
private WireMockServer topLevelClassTodoService;
37+
38+
@Nested
39+
@DisplayName("Test Something")
40+
class NestedTest {
41+
42+
@InjectWireMock("todo-service")
43+
private WireMockServer nestedClassTodoService;
44+
45+
@Test
46+
void injectsWiremockServerToNestedClassField() {
47+
this.assertWireMockServer(
48+
this.nestedClassTodoService, "todo-service.url", "todo-service.port");
49+
}
50+
51+
@Test
52+
void injectsWiremockServerToTopLevelClassField() {
53+
this.assertWireMockServer(
54+
NestedClassSingleWireMockTest.this.topLevelClassTodoService,
55+
"todo-service.url",
56+
"todo-service.port");
57+
}
58+
59+
private void assertWireMockServer(
60+
final WireMockServer wireMockServer, final String property, final String portProperty) {
61+
assertThat(wireMockServer).as("creates WireMock instance").isNotNull();
62+
assertThat(wireMockServer.baseUrl()).as("WireMock baseUrl is set").isNotNull();
63+
assertThat(wireMockServer.port()).as("sets random port").isNotZero();
64+
assertThat(
65+
Integer.valueOf(
66+
NestedClassSingleWireMockTest.this.environment.getProperty(portProperty)))
67+
.as("sets Spring port property")
68+
.isEqualTo(wireMockServer.port());
69+
assertThat(NestedClassSingleWireMockTest.this.environment.getProperty(property))
70+
.as("sets Spring property")
71+
.isEqualTo(wireMockServer.baseUrl());
72+
73+
// Test that WireMock is configured for the correct WireMock instance
74+
// Suffixed with port to make it differ for different test runs and servers
75+
final String mockedPath = "/the_default_prop_mock-" + wireMockServer.port();
76+
WireMock.stubFor(get(mockedPath).willReturn(aResponse().withStatus(202)));
77+
RestAssured.baseURI = wireMockServer.baseUrl();
78+
RestAssured.when().get(mockedPath).then().statusCode(202);
79+
}
80+
}
81+
}

wiremock-spring-boot-example/src/test/java/app/DefaultPropertiesTest.java

+19-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
44
import static com.github.tomakehurst.wiremock.client.WireMock.get;
5+
import static org.assertj.core.api.Assertions.assertThat;
56

7+
import com.github.tomakehurst.wiremock.WireMockServer;
68
import com.github.tomakehurst.wiremock.client.WireMock;
79
import io.restassured.RestAssured;
810
import org.junit.jupiter.api.BeforeEach;
911
import org.junit.jupiter.api.Test;
1012
import org.springframework.beans.factory.annotation.Value;
1113
import org.springframework.boot.test.context.SpringBootTest;
1214
import org.wiremock.spring.EnableWireMock;
15+
import org.wiremock.spring.InjectWireMock;
1316

1417
@SpringBootTest
1518
@EnableWireMock
@@ -21,14 +24,26 @@ class DefaultPropertiesTest {
2124
@Value("${wiremock.server.port}")
2225
private String wiremockPort;
2326

27+
@InjectWireMock WireMockServer wireMockServer;
28+
2429
@BeforeEach
25-
public void before() {
26-
WireMock.stubFor(get("/the_default_prop_mock").willReturn(aResponse().withStatus(202)));
27-
}
30+
public void before() {}
2831

2932
@Test
30-
void test() {
33+
void testCanInvoke() {
34+
WireMock.stubFor(get("/the_default_prop_mock").willReturn(aResponse().withStatus(202)));
35+
3136
RestAssured.baseURI = this.wiremockUrl;
3237
RestAssured.when().get("/the_default_prop_mock").then().statusCode(202);
3338
}
39+
40+
@Test
41+
void testUrlNotNull() {
42+
assertThat(this.wiremockUrl).isNotNull();
43+
}
44+
45+
@Test
46+
void testPortNotNull() {
47+
assertThat(this.wiremockPort).isNotNull();
48+
}
3449
}

0 commit comments

Comments
 (0)