Skip to content

Commit 8fb199f

Browse files
authored
Mock TestcontainersConfiguration in ReusabilityUnitTests (#2080)
1 parent b756527 commit 8fb199f

File tree

3 files changed

+69
-17
lines changed

3 files changed

+69
-17
lines changed

core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.testcontainers.utility;
22

3+
import com.google.common.annotations.VisibleForTesting;
34
import lombok.*;
45
import lombok.extern.slf4j.Slf4j;
56
import org.testcontainers.UnstableAPI;
@@ -9,6 +10,7 @@
910
import java.net.URL;
1011
import java.util.Objects;
1112
import java.util.Properties;
13+
import java.util.concurrent.atomic.AtomicReference;
1214
import java.util.stream.Stream;
1315

1416
/**
@@ -24,7 +26,14 @@ public class TestcontainersConfiguration {
2426
private static File ENVIRONMENT_CONFIG_FILE = new File(System.getProperty("user.home"), "." + PROPERTIES_FILE_NAME);
2527

2628
@Getter(lazy = true)
27-
private static final TestcontainersConfiguration instance = loadConfiguration();
29+
private static final TestcontainersConfiguration instance = loadConfiguration();;
30+
31+
@SuppressWarnings({"ConstantConditions", "unchecked", "rawtypes"})
32+
@VisibleForTesting
33+
static AtomicReference<TestcontainersConfiguration> getInstanceField() {
34+
// Lazy Getter from Lombok changes the field's type to AtomicReference
35+
return (AtomicReference) (Object) instance;
36+
}
2837

2938
@Getter(AccessLevel.NONE)
3039
private final Properties environmentProperties;

core/src/test/java/org/testcontainers/containers/ReusabilityUnitTests.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import com.github.dockerjava.core.command.StartContainerCmdImpl;
1212
import lombok.RequiredArgsConstructor;
1313
import lombok.experimental.FieldDefaults;
14-
import org.junit.Assume;
14+
import org.junit.Rule;
1515
import org.junit.Test;
1616
import org.junit.experimental.runners.Enclosed;
1717
import org.junit.runner.RunWith;
@@ -23,6 +23,7 @@
2323
import org.testcontainers.DockerClientFactory;
2424
import org.testcontainers.containers.startupcheck.StartupCheckStrategy;
2525
import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy;
26+
import org.testcontainers.utility.MockTestcontainersConfigurationRule;
2627
import org.testcontainers.utility.TestcontainersConfiguration;
2728

2829
import java.util.ArrayList;
@@ -128,9 +129,8 @@ protected void containerIsStarted(InspectContainerResponse containerInfo, boolea
128129

129130
@Test
130131
public void shouldSetLabelsIfEnvironmentDoesNotSupportReuse() {
131-
// TODO mock TestcontainersConfiguration
132-
Assume.assumeFalse("does not support reuse", TestcontainersConfiguration.getInstance().environmentSupportsReuse());
133-
AtomicReference<CreateContainerCmd> commandRef = new AtomicReference<>();
132+
Mockito.doReturn(false).when(TestcontainersConfiguration.getInstance()).environmentSupportsReuse();
133+
134134
String containerId = randomContainerId();
135135
when(client.createContainerCmd(any())).then(createContainerAnswer(containerId));
136136
when(client.listContainersCmd()).then(listContainersAnswer());
@@ -147,8 +147,7 @@ public void shouldSetLabelsIfEnvironmentDoesNotSupportReuse() {
147147

148148
@Test
149149
public void shouldCallHookIfReused() {
150-
// TODO mock TestcontainersConfiguration
151-
Assume.assumeTrue("supports reuse", TestcontainersConfiguration.getInstance().environmentSupportsReuse());
150+
Mockito.doReturn(true).when(TestcontainersConfiguration.getInstance()).environmentSupportsReuse();
152151
String containerId = randomContainerId();
153152
when(client.createContainerCmd(any())).then(createContainerAnswer(containerId));
154153
String existingContainerId = randomContainerId();
@@ -200,8 +199,7 @@ public void shouldStartIfListReturnsEmpty() {
200199

201200
@Test
202201
public void shouldReuseIfListReturnsID() {
203-
// TODO mock TestcontainersConfiguration
204-
Assume.assumeTrue("supports reuse", TestcontainersConfiguration.getInstance().environmentSupportsReuse());
202+
Mockito.doReturn(true).when(TestcontainersConfiguration.getInstance()).environmentSupportsReuse();
205203
String containerId = randomContainerId();
206204
when(client.createContainerCmd(any())).then(createContainerAnswer(containerId));
207205
String existingContainerId = randomContainerId();
@@ -216,8 +214,7 @@ public void shouldReuseIfListReturnsID() {
216214

217215
@Test
218216
public void shouldSetLabelsIfEnvironmentDoesNotSupportReuse() {
219-
// TODO mock TestcontainersConfiguration
220-
Assume.assumeFalse("does not support reuse", TestcontainersConfiguration.getInstance().environmentSupportsReuse());
217+
Mockito.doReturn(false).when(TestcontainersConfiguration.getInstance()).environmentSupportsReuse();
221218
AtomicReference<CreateContainerCmd> commandRef = new AtomicReference<>();
222219
String containerId = randomContainerId();
223220
when(client.createContainerCmd(any())).then(createContainerAnswer(containerId, commandRef::set));
@@ -236,19 +233,29 @@ public void shouldSetLabelsIfEnvironmentDoesNotSupportReuse() {
236233
}
237234

238235
@FieldDefaults(makeFinal = true)
239-
static abstract class AbstractReusabilityTest {
236+
public static abstract class AbstractReusabilityTest {
237+
238+
@Rule
239+
public MockTestcontainersConfigurationRule configurationMock = new MockTestcontainersConfigurationRule();
240240

241241
protected DockerClient client = Mockito.mock(DockerClient.class);
242242

243243
protected <T extends GenericContainer<?>> T makeReusable(T container) {
244244
container.dockerClient = client;
245245
container.withNetworkMode("none"); // to disable the port forwarding
246246
container.withStartupCheckStrategy(new StartupCheckStrategy() {
247-
@Override
248-
public StartupStatus checkStartupState(DockerClient dockerClient, String containerId) {
249-
return StartupStatus.SUCCESSFUL;
250-
}
251-
});
247+
248+
@Override
249+
public boolean waitUntilStartupSuccessful(DockerClient dockerClient, String containerId) {
250+
// Skip DockerClient rate limiter
251+
return true;
252+
}
253+
254+
@Override
255+
public StartupStatus checkStartupState(DockerClient dockerClient, String containerId) {
256+
return StartupStatus.SUCCESSFUL;
257+
}
258+
});
252259
container.waitingFor(new AbstractWaitStrategy() {
253260
@Override
254261
protected void waitUntilReady() {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.testcontainers.utility;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.junit.rules.TestRule;
5+
import org.junit.runner.Description;
6+
import org.junit.runners.model.Statement;
7+
import org.mockito.Mockito;
8+
9+
import java.util.concurrent.atomic.AtomicReference;
10+
11+
/**
12+
* This {@link TestRule} applies a spy on {@link TestcontainersConfiguration}
13+
* for testing features that depend on the global configuration.
14+
*/
15+
public class MockTestcontainersConfigurationRule implements TestRule {
16+
17+
static AtomicReference<TestcontainersConfiguration> REF = TestcontainersConfiguration.getInstanceField();
18+
19+
@NotNull
20+
@Override
21+
public Statement apply(@NotNull Statement base, @NotNull Description description) {
22+
return new Statement() {
23+
@Override
24+
public void evaluate() throws Throwable {
25+
TestcontainersConfiguration previous = REF.get();
26+
REF.set(Mockito.spy(previous));
27+
28+
try {
29+
base.evaluate();
30+
} finally {
31+
REF.set(previous);
32+
}
33+
}
34+
};
35+
}
36+
}

0 commit comments

Comments
 (0)