JUnit 5 所有类测试完成后如何从 docker 删除测试容器

问题描述 投票:0回答:1
  • 我们在这里创建容器
  • 项目中还有一个属性
    ryuk.container.image=testcontainers/ryuk:0.3.3
    ,它创建一个容器,该容器应在测试完成后删除所有测试容器,但由于某种原因,删除并未发生

public class TestContainersSpringContextCustomizerFactory implements ContextCustomizerFactory {

  private static SqlTestContainer prodTestContainer;
  private static S3TestContainer minioContainer;
  private static ElasticsearchTestContainer elasticsearchBean;
  private static RabbitMQTestContainer rabbitMQContainer;
  private Logger log = LoggerFactory.getLogger(TestContainersSpringContextCustomizerFactory.class);

  @Override
  public ContextCustomizer createContextCustomizer(Class<?> testClass,
                                                   List<ContextConfigurationAttributes> configAttributes) {
    return (context, mergedConfig) -> {
      ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
      TestPropertyValues testValues = TestPropertyValues.empty();

      EmbeddedElasticsearch elasticsearchAnnotation = AnnotatedElementUtils.findMergedAnnotation(
          testClass,
          EmbeddedElasticsearch.class
      );
      if (null != elasticsearchAnnotation) {
        log.debug("detected the EmbeddedElasticsearch annotation on class {}", testClass.getName());
        log.info("Warming up the elastic database");
        if (null == elasticsearchBean) {
          elasticsearchBean = beanFactory.createBean(ElasticsearchTestContainer.class);
          beanFactory.registerSingleton(ElasticsearchTestContainer.class.getName(),
              elasticsearchBean);
          // ((DefaultListableBeanFactory)beanFactory).registerDisposableBean(ElasticsearchTestContainer.class.getName(), elasticsearchBean);
        }
        testValues =
            testValues.and(
                "spring.elasticsearch.uris=http://"
                    + elasticsearchBean.getElasticsearchContainer().getHttpHostAddress()
            );
      }
//similary code other for other containers
}

作为示例,我将向您展示 4 个容器之一的代码,其余的写法类似

public class TestContainersSpringContextCustomizerFactory implements ContextCustomizerFactory {

  private static SqlTestContainer prodTestContainer;
  private static S3TestContainer minioContainer;
  private static ElasticsearchTestContainer elasticsearchBean;
  private static RabbitMQTestContainer rabbitMQContainer;
  private Logger log = LoggerFactory.getLogger(TestContainersSpringContextCustomizerFactory.class);

  @Override
  public ContextCustomizer createContextCustomizer(Class<?> testClass,
                                                   List<ContextConfigurationAttributes> configAttributes) {
    return (context, mergedConfig) -> {
      ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
      TestPropertyValues testValues = TestPropertyValues.empty();

      EmbeddedElasticsearch elasticsearchAnnotation = AnnotatedElementUtils.findMergedAnnotation(
          testClass,
          EmbeddedElasticsearch.class
      );
      if (null != elasticsearchAnnotation) {
        log.debug("detected the EmbeddedElasticsearch annotation on class {}", testClass.getName());
        log.info("Warming up the elastic database");
        if (null == elasticsearchBean) {
          elasticsearchBean = beanFactory.createBean(ElasticsearchTestContainer.class);
          beanFactory.registerSingleton(ElasticsearchTestContainer.class.getName(),
              elasticsearchBean);
          // ((DefaultListableBeanFactory)beanFactory).registerDisposableBean(ElasticsearchTestContainer.class.getName(), elasticsearchBean);
        }
        testValues =
            testValues.and(
                "spring.elasticsearch.uris=http://"
                    + elasticsearchBean.getElasticsearchContainer().getHttpHostAddress()
            );
      }
//similary code other for other containers
}
java spring junit5 testcontainers testcontainers-junit5
1个回答
0
投票

根据我对您的问题和测试容器的理解,问题是在容器上设置此属性:


/**
 * Base class for starting/stopping ElasticSearch during tests.
 */
public class ElasticsearchTestContainer implements InitializingBean, DisposableBean {

  private static final Logger log = LoggerFactory.getLogger(ElasticsearchTestContainer.class);
  private static final Integer CONTAINER_STARTUP_TIMEOUT_MINUTES = 10;
  private ElasticsearchContainer elasticsearchContainer;

  @Override
  public void destroy() {
    if (null != elasticsearchContainer && elasticsearchContainer.isRunning()) {
      elasticsearchContainer.close();
    }
  }

  @Override
  public void afterPropertiesSet() {
    if (null == elasticsearchContainer) {
      elasticsearchContainer =
          new ElasticsearchContainer(
              DockerImageName.parse("docker-persistent.nexus.jaga.rt.ru/elasticsearch")
                  .asCompatibleSubstituteFor("docker.elastic.co/elasticsearch/elasticsearch")
                  .withTag("7.17.4"))
              .withStartupTimeout(
                  Duration.of(CONTAINER_STARTUP_TIMEOUT_MINUTES, ChronoUnit.MINUTES))
              .withSharedMemorySize(256000000L)
              .withEnv("ES_JAVA_OPTS", "-Xms256m -Xmx256m")
              .withEnv("xpack.security.enabled", "false")
              .withLogConsumer(new Slf4jLogConsumer(log))
              .withReuse(true);
    }
    if (!elasticsearchContainer.isRunning()) {
      elasticsearchContainer.start();
    }
  }

  public ElasticsearchContainer getElasticsearchContainer() {
    return elasticsearchContainer;
  }
}
。 将此属性设置为 true 时,容器将在 JVM 进程中重用,这意味着框架不会在测试运行完成后删除它们。

© www.soinside.com 2019 - 2024. All rights reserved.