I'm not sure if there is something out-of-the-box for this in Testcontainers for JUnit 4. You can mirror the JUnit 5 feature with some custom code.
First, you need a way to conditionally execute tests. There is already a good answer for this available. Basically you use JUnit 4 Assumptions for this:
@Before
public void beforeMethod() {
org.junit.Assume.assumeTrue(someCondition());
// rest of setup.
}
You will need this for all your Docker related tests.
Next, someCondition()
should evaluate whether Docker is available or not. The current Testcontainers (1.14.3) release uses the following code part for @Testcontainers(disabledWithoutDocker = true)
:
private ConditionEvaluationResult evaluate(Testcontainers testcontainers) {
if (testcontainers.disabledWithoutDocker()) {
if (isDockerAvailable()) {
return ConditionEvaluationResult.enabled("Docker is available");
}
return ConditionEvaluationResult.disabled("disabledWithoutDocker is true and Docker is not available");
}
return ConditionEvaluationResult.enabled("disabledWithoutDocker is false");
}
boolean isDockerAvailable() {
try {
DockerClientFactory.instance().client();
return true;
} catch (Throwable ex) {
return false;
}
}
So you could extract isDockerAvailable()
to e.g. an abstract class that also includes the @Before
and handle this for yourself:
public abstract class DockerizedTest {
@Before
public void shouldRunTest() {
org.junit.Assume.assumeTrue(isDockerAvailable());
}
boolean isDockerAvailable() {
try {
DockerClientFactory.instance().client();
return true;
} catch (Throwable ex) {
return false;
}
}
}
and now all your Docker related tests can extend DockerizedTest
. Whenever the assumption evaluates to false, the test will be ignored.
If @Before
is too late, you can use the same approach with @BeforeClass
.