如何使用 junit5 和 testcontainers 测试存储库?

     2023-03-28     248

关键词:

【中文标题】如何使用 junit5 和 testcontainers 测试存储库?【英文标题】:How to test repository with junit5 and testcontainers? 【发布时间】:2021-02-10 16:21:15 【问题描述】:

我有一个示例项目,我在其中试验不同的技术。

我有以下设置:

Spring Boot 2.3.4.RELEASE 飞路 7.0.1 测试容器 1.15.0-rc2 Junit 5.7.0

如何使用 testcontainer-junit5 测试 Repository 层?

我现在为CompanyRepositoryTest.java 提供的代码示例:

@ExtendWith(SpringExtension.class)
@Testcontainers
public class CompanyRepositoryTest 

    @Autowired
    private CompanyRepository companyRepository;

    @Container
    public MySQLContainer mysqlContainer = new MySQLContainer()
            .withDatabaseName("foo")
            .withUsername("foo")
            .withPassword("secret");;

    
    @Test
    public void whenFindByIdExecuted_thenNullReturned()
            throws Exception 
        assertEquals(companyRepository.findById(1L), Optional.ofNullable(null));
    

    @Test
    public void whenFindAllExecuted_thenEmptyListReturned() 
        assertEquals(companyRepository.findAll(), new ArrayList<>());
    

当我添加@SpringBootTest 时,我需要设置所有上下文并且有一些应用程序加载上下文问题?

问题是,谁能揭开@TestContainers 注释的作用?在测试存储库时使用它的最佳做法或正确做法是什么?

【问题讨论】:

除了已经很好的答案外,本指南还讨论了 Testcontainers + Spring Boot + JUnit (4/5) 的所有可能设置方式:rieckpil.de/… 【参考方案1】:

@Testcontainers 注释提供的JUnit 5 extension 会扫描使用@Container 注释声明的任何容器,然后启动和停止这些容器以进行测试。作为静态字段的容器将与所有测试共享,作为实例字段的容器将为每个测试启动和停止。

如果您使用 Spring Boot,为测试设置测试容器的最简单方法可能是在 application-test.yml 中提供属性。这将使用数据源 JDBC URL 来启动 testcontainers 容器。有关详细信息,请参阅 Testcontainers JDBC support。

您也可以使用@DataJpaTest 而不是@SpringBootTest 仅测试存储库层:

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")
class CompanyRepositoryTest  

您的application-test.yml 文件:

spring:
  datasource:
    url: jdbc:tc:mysql:8.0://hostname/databasename
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver

在某些情况下,您可能还想使用@TestPropertySource 注释:

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(
    properties = 
        "spring.datasource.url = jdbc:tc:mysql:8.0://hostname/test-database",
        "spring.datasource.driver-class-name = org.testcontainers.jdbc.ContainerDatabaseDriver"
    
)
class CompanyRepositoryTest  

请注意,hostnametest-database 实际上并未在任何地方使用。

【讨论】:

【参考方案2】:

你说

当我添加@SpringBootTest 时,我需要设置所有上下文并拥有 一些应用程序加载上下文问题?

如果您想尝试替代方案并且 Testcontainer 不是强制性的,您可以采用不同的方式。

使用SpringBootTest注解不需要加载everyting,可以指定需要哪些类如

@SpringBootTest(classes =  TheService.class )

或者使用@Import注解

并嘲笑其他人,例如

@MockBean
MyService service;

对于数据库连接,您可以使用注释,例如

@ActiveProfiles("my-profile-for-jpa-test")
@DataJpaTest
@EnableJpaAuditing
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)

编辑:我觉得这应该是一个评论,但我想用正确的格式解决问题的 SpringBootTest 部分

【讨论】:

这是一个不错的答案,但我也想使用测试容器。作为我想要评估的技术之一。另外,我特别想要 testcontainers + junit5,因为我使用过 testconatiners + junit4,并且网上有很多关于它的用法的参考资料,但还不是 junit5。【参考方案3】:

这是一个例子,我是如何在 Spring 中使用 MySql 配置 Liquibase(类似于 Flyway 的框架):

@DataJpaTest
@TestPropertySource(properties = "spring.jpa.hibernate.ddl-auto=validate")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers =  MySqlLiquibaseBaseIT.Initializer.class )
@Testcontainers
public class MySqlLiquibaseBaseIT 

  @Container
  public static MySQLContainer<?> mysql = new MySQLContainer<>(
    DockerImageName
      .parse(MySQLContainer.NAME)
      .withTag("5.7.22"));

  @Configuration
  @EnableJpaRepositories
  @EntityScan
  static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> 
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) 
      TestPropertyValues.of(
        "spring.datasource.url=" + mysql.getJdbcUrl(),
        "spring.datasource.username=" + mysql.getUsername(),
        "spring.datasource.password=" + mysql.getPassword(),
        "spring.datasource.driver-class-name=" + mysql.getDriverClassName())
        .applyTo(configurableApplicationContext.getEnvironment());
    

    @Bean
    public SpringLiquibase springLiquibase(DataSource dataSource) 
      SpringLiquibase liquibase = new SpringLiquibase();
      liquibase.setDropFirst(true);
      liquibase.setDataSource(dataSource);
      liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.yml");
      return liquibase;
    
  

完整的MySqlLiquibaseBaseIT.java

【讨论】:

【参考方案4】:
    根据docs:

测试容器扩展查找所有带有注释的字段 Container 并调用它们的容器生命周期方法。容器 声明为静态字段将在测试方法之间共享。他们 在执行任何测试方法之前只会启动一次,并且 在最后一个测试方法执行后停止。声明的容器 因为每个测试方法都会启动和停止实例字段。

因此,在您的情况下,它将为每个测试方法重新创建一个容器,它只负责启动和停止容器。如果您需要一些测试数据 - 必须手动完成,我看到您有 Flyway,应该这样做。

    你在说什么“上下文问题”?

    存储库通常不单独测试,您可以只测试运行存储库方法的服务,而不是为两者编写测试。如果您仍然想测试 repos - 用 @Before 中的一些数据填充数据库。

如果您有更多问题,请提出。

【讨论】:

单独集成测试存储库(或取决于您的架构,持久层)非常好。这就是 @DataJpaTest 的用途。

如何使用 JUnit 5 在 Kotlin 中创建 TestContainers 基测试类

】如何使用JUnit5在Kotlin中创建TestContainers基测试类【英文标题】:HowtocreateaTestContainersbasetestclassinKotlinwithJUnit5【发布时间】:2019-09-2915:58:30【问题描述】:我正在尝试将Neo4jTestContainers与Kotlin、SpringDataNeo4j、SpringBoot和JUnit5一起使... 查看详情

如何使用 Junit 5 使用 Testcontainer 对 Kafka 运行集成测试

】如何使用Junit5使用Testcontainer对Kafka运行集成测试【英文标题】:HowcanIrunIntegrationTesttoKafkawithTestcontainerusingJunit5【发布时间】:2019-12-2120:47:57【问题描述】:我正在尝试为我的Kafka消费者编写集成测试。我正在使用JUnit5,所以我... 查看详情

使用 Micronaut 应用程序为 JUnit5 中的每个单元/集成测试运行一次 TestContainer

...Micronaut应用程序为JUnit5中的每个单元/集成测试运行一次TestContainer【英文标题】:RunningTestContaineronceforeachUnit/IntegrationtestinJUnit5withMicronautapplication【发布时间】:2021-10-1707:33:55【问题描述】:我在Micronaut应用程序中使用带有JUnit5... 查看详情

如何将 Testcontainers 与 @DataJpaTest 结合使用以避免代码重复?

】如何将Testcontainers与@DataJpaTest结合使用以避免代码重复?【英文标题】:HowtocombineTestcontainerswith@DataJpaTestavoidingcodeduplication?【发布时间】:2021-10-0615:54:08【问题描述】:我想通过JUnit5将Testcontainers与@DataJpaTest(和@SpringBootTest)... 查看详情

JUnit 5 和具有不同扩展的继承,用于使用 TestContainers 进行 Spring Boot 集成测试

】JUnit5和具有不同扩展的继承,用于使用TestContainers进行SpringBoot集成测试【英文标题】:JUnit5andinheritancewithdifferentextensionsforSpringBootIntegrationtestwithTestContainers【发布时间】:2021-08-2116:50:30【问题描述】:简介:我们的产品需要对3... 查看详情

如何使用 Testcontainers 将可执行文件复制到 Docker 容器

】如何使用Testcontainers将可执行文件复制到Docker容器【英文标题】:HowtocopyexecutablefiletoDockercontainerusingTestcontainers【发布时间】:2020-07-3004:12:35【问题描述】:我正在尝试将可执行的初始化bash脚本init.sh复制到使用JUnit5模块使用Tes... 查看详情

当 pom.xml 中存在 TestContainers 依赖项时,未检测到 JUnit 5 测试

】当pom.xml中存在TestContainers依赖项时,未检测到JUnit5测试【英文标题】:JUnit5testsnotdetectedwhenTestContainersdependenciesexistinpom.xml【发布时间】:2021-07-0715:37:29【问题描述】:我有一个使用TestContainers(最新1.5.2)和JUnit5(5.7.0)测试的mave... 查看详情

在 SpringBoot 中使用 Testcontainers 进行 Spring Data Elasticsearch 集成测试

】在SpringBoot中使用Testcontainers进行SpringDataElasticsearch集成测试【英文标题】:SpringDataElasticsearchintegrationtestusingTestcontainersinSpringBoot【发布时间】:2021-05-0207:29:38【问题描述】:我正在尝试使用Testcontainers和junit5在SpringBoot中为SpringD... 查看详情

使用 @DynamicPropertySource 的 TestContainers、Spring Webflux、JUnit 5、MySQLR2DBCDatabaseContainer

】使用@DynamicPropertySource的TestContainers、SpringWebflux、JUnit5、MySQLR2DBCDatabaseContainer【英文标题】:TestContainers,SpringWebflux,JUnit5,MySQLR2DBCDatabaseContainerusing@DynamicPropertySource【发布时间】:2020-12-0915:35:17【问题描述】:我正 查看详情

stderr 和 stdout 被 testcontainers-java 中的换行符随机中断

】stderr和stdout被testcontainers-java中的换行符随机中断【英文标题】:Stderrandstdoutinterruptedrandomlybynewlinecharsintestcontainers-java【发布时间】:2021-06-0710:09:14【问题描述】:我正在使用Testcontainers运行Junit5测试,在测试中我使用Maven启动... 查看详情

如何使用 testcontainers 和 spring-kafka 准备测试

】如何使用testcontainers和spring-kafka准备测试【英文标题】:Howtopreparetestsusingtestcontainersandspring-kafka【发布时间】:2020-10-1910:14:04【问题描述】:我正在尝试为kafka消息传递设置我的集成测试,并从使用Embedded-Kafka转为使用Testcontaine... 查看详情

使用 testcontainers 测试 kafka 和 spark

】使用testcontainers测试kafka和spark【英文标题】:testingkafkaandsparkwithtestcontainers【发布时间】:2021-10-2502:18:01【问题描述】:我正在尝试与testcontainers一起检查流式管道作为集成测试,但我不知道如何获取bootstrapServers,至少在最后... 查看详情

在 JUnit 5 中使用 @TestContainers 实现 @DataJpaTest

】在JUnit5中使用@TestContainers实现@DataJpaTest【英文标题】:Spring@DataJpaTestwith@TestContainersinJUnit5【发布时间】:2021-03-1500:32:04【问题描述】:这是对Spring@DataJpaTestwithJUnit5的扩展,主要区别在于添加了测试容器。我试图在git-reposample中... 查看详情

带有硒测试容器的junit5无法正常工作

...试容器的junit5无法正常工作【英文标题】:junit5withseleniumtestcontainernotworking【发布时间】:2021-11-2015:36:53【问题描述】:目标-我希望能够使用Junit5和testcontainers编写selenium测试。我正在编写一个非常简单的代码,以便能够检查谷... 查看详情

如何使用 SpringBoot2、JUnit5 和 Kotlin 将配置属性注入单元测试

】如何使用SpringBoot2、JUnit5和Kotlin将配置属性注入单元测试【英文标题】:HowcanIinjectconfigpropertiesintoaunittest,usingSpringBoot2,JUnit5,andKotlin【发布时间】:2018-12-2202:03:35【问题描述】:我的场景:我正在构建一个使用Kotlin和SpringBoot2.0.3... 查看详情

如何运行自定义 docker 镜像 testContainer

】如何运行自定义docker镜像testContainer【英文标题】:HowtorunacustomdockerimagetestContainer【发布时间】:2020-11-1220:38:22【问题描述】:我浏览了多个博客和官方文档,但无法解决我的问题。我正在使用testContainers-scala版本0.38.1和scala版... 查看详情

如何使用 Testcontainers Cassandra 和 Spring Data for Apache Cassandra?

】如何使用TestcontainersCassandra和SpringDataforApacheCassandra?【英文标题】:HowtouseTestcontainersCassandrawithSpringDataforApacheCassandra?【发布时间】:2019-12-2300:54:26【问题描述】:我为我的SpringBoot应用程序开发集成测试,该应用程序与Cassandra... 查看详情

如何在 JUnit5 中使用 Mockito

】如何在JUnit5中使用Mockito【英文标题】:HowtouseMockitowithJUnit5【发布时间】:2017-04-1901:36:39【问题描述】:如何在Mockito和JUnit5中使用注入?在JUnit4中,我可以只使用@RunWith(MockitoJUnitRunner.class)注释。在JUnit5中是没有@RunWith注解?【... 查看详情