【问题标题】:JUnit 5 and inheritance with different extensions for Spring Boot Integration test with TestContainersJUnit 5 和具有不同扩展的继承,用于使用 TestContainers 进行 Spring Boot 集成测试
【发布时间】:2021-08-21 16:50:30
【问题描述】:

简介: 我们的产品需要对 3 个不同的数据库进行集成测试:

  1. 甲骨文
  2. Postgres
  3. MSSQL

我们使用 Spring Boot 作为我们的框架和 TestContainers 来启动上述数据库。

问题: 我们需要为每个容器(数据库)运行相同的测试。

在网上大量挖掘之后,我能想到的唯一方法是使用 BaseClass,我们在其中编写所有测试用例,并为每个容器创建一个继承自 BaseClass 的类,并重写该方法并用@Test 注释它。

在下面的代码中,您将为 Postgres 提供一个单独的 JUnit5 扩展,它启动一个 TestContainer、基测试类和一个从 Postgres 扩展扩展的测试类,启动一个 Spring 应用程序上下文,并从基运行测试类。

代码:

import com.company.itest.AutoConfig;
import com.company.itest.BaseIntegrationTest;
import com.company.itest.db.mssql.MSSqlTest;
import com.company.itest.db.oracle.OracleTest;
import com.company.itest.db.postgres.PostgresTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

public class TestTheTest extends BaseIntegrationTest {
  public void contextLoads() {
    Assertions.assertEquals(1, 1);
  }
  public void contextLoads2() {
    Assertions.assertNotEquals(1, 2);
  }
}


@SpringBootTest(
    classes = AutoConfig.class,
    webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@PostgresTest
class TestPostgres extends TestTheTest {
  @Test
  public void contextLoads() {
    super.contextLoads();
  }
  @Test
  public void contextLoads2() {
    super.contextLoads2();
  }
}


import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.PostgreSQLContainer;

public class PostgresqlTestContainersExtension implements BeforeAllCallback, AfterAllCallback {

  private final Logger log = LoggerFactory.getLogger(PostgresqlTestContainersExtension.class);

  private PostgreSQLContainer<?> postgres;

  @Override
  public void beforeAll(ExtensionContext context) {
    log.info("Setting up postgres container");
    postgres = new PostgreSQLContainer<>("postgres:13").withReuse(true);

    postgres.start();
    System.setProperty("spring.datasource.url", postgres.getJdbcUrl());
    System.setProperty("spring.datasource.username", postgres.getUsername());
    System.setProperty("spring.datasource.password", postgres.getPassword());
  }

  @Override
  public void afterAll(ExtensionContext context) {
    postgres.stop();
  }
}



package com.company.itest.db.postgres;

import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@ExtendWith(SpringExtension.class)
@ExtendWith({PostgresqlTestContainersExtension.class})
@Testcontainers
public @interface PostgresTest {}

问题:

如何创建单个 JUnit 测试类,然后使用不同的 JUnit5 扩展重新运行它而不执行这种多态性?

【问题讨论】:

  • 您可以在默认方法中实现带有测试的接口,而不是扩展超类。不过,这仍然是一种多态方法。对于少数变体,例如 3 个不同的数据库,我认为这种方法是可以接受的。

标签: java spring-boot integration-testing junit5 testcontainers


【解决方案1】:

如果您使用的是 maven,您可以尝试为每个 db 设置不同的配置文件

【讨论】:

    猜你喜欢
    • 2019-02-19
    • 2017-12-19
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 2019-08-17
    • 2018-02-01
    • 2019-05-21
    • 2019-05-30
    相关资源
    最近更新 更多