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

问题描述

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

我有以下设置:

  • Spring Boot 2.3.4.RELEASE
  • Flyway 7.0.1
  • 测试容器1.15.0-rc2
  • Junit 5.7.0

如何使用testcontainer-junit5测试存储库层?

我现在为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注释的作用吗?在测试存储库时,最佳做法是什么或正确使用它?

解决方法

# Simplified version bash "Install gems" do code <<~EOF bundle config --local deployment true && bundle config --local path /path/to/gems_dir && bundle install --gemfile=/path/to/Gemfile EOF user "target_user" group "target_user" end 注释提供的JUnit 5 extension扫描使用@Testcontainers注释声明的所有容器,然后启动和停止这些容器以进行测试。容器作为静态字段将与所有测试共享,容器(作为实例字段)将在每个测试中启动和停止。

如果您使用的是Spring Boot,则为测试设置测试容器的最简单方法可能是在@Container中提供属性。这将使用数据源JDBC URL启动testcontainers容器。有关更多信息,请参阅测试容器JDBC support

您还可以使用application-test.yml而非@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 { } hostname实际上并没有在任何地方使用。

,

你说

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

如果您想尝试其他方法,而Testcontainer不是强制性的,则可以采用其他方法。

使用SpringBootTest批注时不需要加载所有内容,您可以指定所需的类,例如

@SpringBootTest(classes = { TheService.class })

或使用@Import批注

并嘲笑其他人,例如

@MockBean
MyService service;

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

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

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

,
  1. 根据docs

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

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

  1. 您在说什么“上下文问题”?

  2. 存储库通常不单独进行测试,您可以仅测试运行存储库方法的服务,而不必为这两种方法编写测试。如果仍然要测试存储库,请在@Before中向数据库填充一些数据。

如果您还有其他问题,请询问。

,

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

Call Shell("cmd.exe",vbNormalFocus)

完整的MySqlLiquibaseBaseIT.java

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...