From 0b4164174a909debddabec77385a10ceabf2a2c6 Mon Sep 17 00:00:00 2001 From: Tomas Bjerre Date: Sun, 8 Dec 2024 11:14:59 +0100 Subject: [PATCH] feat: optionally disable reset to enable concurrency (refs #70) --- .../wiremock/spring/ConfigureWireMock.java | 10 ++ .../WireMockSpringJunitExtension.java | 21 +++- .../ResetWireMockDisabledBetweenTest.java | 106 ++++++++++++++++++ 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/test/java/usecases/ResetWireMockDisabledBetweenTest.java diff --git a/src/main/java/org/wiremock/spring/ConfigureWireMock.java b/src/main/java/org/wiremock/spring/ConfigureWireMock.java index 5474b7c..3a7bbc4 100644 --- a/src/main/java/org/wiremock/spring/ConfigureWireMock.java +++ b/src/main/java/org/wiremock/spring/ConfigureWireMock.java @@ -115,4 +115,14 @@ * @return the configuration customizers classes */ Class[] configurationCustomizers() default {}; + + /** + * When tests are running concurrently they will break each other if servers are being reset + * between tests. Automatic reset is turned on by default, this option allows a user to turn it + * off. + * + * @return true if {@link WireMockServer} should be invoked with {@link WireMockServer#resetAll()} + * between test runs. + */ + boolean resetWireMockServer() default true; } diff --git a/src/main/java/org/wiremock/spring/internal/WireMockSpringJunitExtension.java b/src/main/java/org/wiremock/spring/internal/WireMockSpringJunitExtension.java index 80d43a3..5ceb667 100644 --- a/src/main/java/org/wiremock/spring/internal/WireMockSpringJunitExtension.java +++ b/src/main/java/org/wiremock/spring/internal/WireMockSpringJunitExtension.java @@ -31,8 +31,7 @@ public class WireMockSpringJunitExtension @Override public void beforeEach(final ExtensionContext extensionContext) throws Exception { - // reset all wiremock servers associated with application context - Store.INSTANCE.findAllInstances(extensionContext).forEach(WireMockServer::resetAll); + this.resetWireMockServersIfConfigured(extensionContext); // inject properties into test class fields injectWireMockInstances(extensionContext, InjectWireMock.class, InjectWireMock::value); @@ -40,6 +39,24 @@ public void beforeEach(final ExtensionContext extensionContext) throws Exception this.configureWireMockForDefaultInstance(extensionContext); } + private void resetWireMockServersIfConfigured(final ExtensionContext extensionContext) { + final List instances = extensionContext.getRequiredTestInstances().getAllInstances(); + for (final Object instance : instances) { + final EnableWireMock enableWireMockAnnotation = + AnnotationUtils.findAnnotation(instance.getClass(), EnableWireMock.class); + if (enableWireMockAnnotation == null) { + continue; + } + final ConfigureWireMock[] wireMockServers = + WireMockContextCustomizerFactory.getConfigureWireMocksOrDefault( + enableWireMockAnnotation.value()); + List.of(wireMockServers).stream() + .filter(it -> it.resetWireMockServer()) + .map(it -> Store.INSTANCE.findRequiredWireMockInstance(extensionContext, it.name())) + .forEach(WireMockServer::resetAll); + } + } + private void configureWireMockForDefaultInstance(final ExtensionContext extensionContext) { final List instances = extensionContext.getRequiredTestInstances().getAllInstances(); WireMockServer wiremock = null; diff --git a/src/test/java/usecases/ResetWireMockDisabledBetweenTest.java b/src/test/java/usecases/ResetWireMockDisabledBetweenTest.java new file mode 100644 index 0000000..68005c3 --- /dev/null +++ b/src/test/java/usecases/ResetWireMockDisabledBetweenTest.java @@ -0,0 +1,106 @@ +package usecases; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.anyRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import io.restassured.RestAssured; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.wiremock.spring.ConfigureWireMock; +import org.wiremock.spring.EnableWireMock; +import org.wiremock.spring.InjectWireMock; + +@SpringBootTest +@EnableWireMock({ + @ConfigureWireMock( + name = "wm1", + portProperties = "wm1.server.port", + baseUrlProperties = "wm1.server.url", + resetWireMockServer = false), + @ConfigureWireMock( + name = "wm2", + portProperties = "wm2.server.port", + baseUrlProperties = "wm2.server.url") +}) +class ResetWireMockDisabledBetweenTest { + + @InjectWireMock("wm1") + private WireMockServer wm1; + + @Value("${wm1.server.port}") + private int wm1Port; + + @Value("${wm1.server.url}") + private String wm1Url; + + @InjectWireMock("wm2") + private WireMockServer wm2; + + @Value("${wm2.server.port}") + private int wm2Port; + + @Value("${wm2.server.url}") + private String wm2Url; + + private WireMock wm1Client; + + private WireMock wm2Client; + + @BeforeEach + public void before() { + this.wm1Client = WireMock.create().port(this.wm1Port).build(); + this.wm2Client = WireMock.create().port(this.wm2Port).build(); + } + + @Test + @Order(1) + void test1() { + this.wm1Client.register( + get("/wm1_configured_in_test1").willReturn(aResponse().withStatus(202))); + this.wm2Client.register( + get("/wm2_configured_in_test1").willReturn(aResponse().withStatus(202))); + + assertThat(this.wm1Client.find(anyRequestedFor(anyUrl()))).hasSize(0); + assertThat(this.wm1Client.allStubMappings().getMappings()).hasSize(1); + + assertThat(this.wm2Client.find(anyRequestedFor(anyUrl()))).hasSize(0); + assertThat(this.wm2Client.allStubMappings().getMappings()).hasSize(1); + + this.wm1Client.register( + get("/wm1_configured_in_test1_again").willReturn(aResponse().withStatus(202))); + + RestAssured.when().get(this.wm1Url + "/wm1_configured_in_test1_again").then().statusCode(202); + + assertThat(this.wm1Client.find(anyRequestedFor(anyUrl()))).hasSize(1); + assertThat(this.wm1Client.allStubMappings().getMappings()).hasSize(2); + + assertThat(this.wm2Client.find(anyRequestedFor(anyUrl()))).hasSize(0); + assertThat(this.wm2Client.allStubMappings().getMappings()).hasSize(1); + } + + @Test + @Order(2) + void test2() { + assertThat(this.wm1Client.find(anyRequestedFor(anyUrl()))) + .as("should not have been reset") + .hasSize(1); + assertThat(this.wm1Client.allStubMappings().getMappings()) + .as("should not have been reset") + .hasSize(2); + + assertThat(this.wm2Client.find(anyRequestedFor(anyUrl()))) + .as("should have been reset") + .hasSize(0); + assertThat(this.wm2Client.allStubMappings().getMappings()) + .as("should have been reset") + .hasSize(0); + } +}