首页 > 解决方案 > 如何在 junit4/testcontainers 中获取 @Testcontainers(disabledWithoutDocker = true) 行为

问题描述

我的代码库很古老并且被锁定在 JUnit4 中。我想将 testcontainers 与项目集成,以将 docker 容器合并到自动化测试中。

我的开发箱(我控制)运行 docker,但是,我的 CI 系统(我不控制)没有。

如果我可以使用 JUnit5,我只需添加@Testcontainers(disabledWithoutDocker = true)注释,基于 docker 的测试将在我的开发盒上愉快地运行,而在 CI 机器上被禁用。

JUnit4 相当于@Testcontainers(disabledWithoutDocker = true)什么?

标签: dockerjunit4junit5testcontainers

解决方案


我不确定在 JUnit 4 的 Testcontainers 中是否有开箱即用的东西。您可以使用一些自定义代码来镜像 JUnit 5 功能。

首先,您需要一种有条件地执行测试的方法。已经有一个很好的答案可用。基本上,您为此使用 JUnit 4 Assumptions:

 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }

您将需要它进行所有与 Docker 相关的测试。

接下来,someCondition()应该评估 Docker 是否可用。当前的 Testcontainers (1.14.3) 版本使用以下代码部分@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;
    }
}

因此,您可以提取isDockerAvailable()到例如一个抽象类,该类还包括@Before并自己处理:

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;
    }
  }

}

现在所有与 Docker 相关的测试都可以扩展DockerizedTest. 每当假设评估为假时,测试将被忽略。

如果@Before为时已,您可以使用与 相同的方法@BeforeClass


推荐阅读