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

Posted

技术标签:

【中文标题】在 JUnit 5 中使用 @TestContainers 实现 @DataJpaTest【英文标题】:Spring @DataJpaTest with @TestContainers in JUnit 5 【发布时间】:2021-03-15 00:32:04 【问题描述】:

这是对Spring @DataJpaTest with JUnit 5 的扩展,主要区别在于添加了测试容器。

我试图在git-repo sample 中保持最少的内容。

测试很简单

@DataJpaTest
@Testcontainers
@ContextConfiguration(classes = 
        DemoApplicationTests.Config.class
)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class DemoApplicationTests 

    @Autowired
    private Artifacts artifacts;

    @Test
    void contextLoads() 
        assertThat(artifacts).isNotNull();
    

    @Container
    private static final mysqlContainer<?> MYSQL = new MySQLContainer<>("mysql:5.7");

    @Configuration
    static class Config 
        @Bean
        public DataSource dataSource() 

            final DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setUrl(MYSQL.getJdbcUrl());
            dataSource.setUsername(MYSQL.getUsername());
            dataSource.setPassword(MYSQL.getPassword());

            await().pollInterval(Duration.ofSeconds(2L))
                    .atMost(Duration.ofMinutes(2L))
                    .until(() -> 
                        try (final Connection c = dataSource.getConnection()) 
                            c.prepareStatement("select 1 from dual");
                            return true;
                         catch (SQLException e) 
                            return false;
                        
                    );

            return dataSource;

        

    


我也尽量减少了主要应用程序

@SpringBootApplication
@EnableTransactionManagement
@EnableJpaRepositories
@EntityScan
public class DemoApplication 

    public static void main(String[] args) 
        SpringApplication.run(DemoApplication.class, args);
    


但运行测试我得到以下堆栈跟踪段:


Caused by: java.lang.IllegalStateException: Unable to retrieve @EnableAutoConfiguration base packages
    at org.springframework.boot.autoconfigure.AutoConfigurationPackages.get(AutoConfigurationPackages.java:78)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport.getBasePackages(AbstractRepositoryConfigurationSourceSupport.java:79)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport$AutoConfiguredAnnotationRepositoryConfigurationSource.getBasePackages(AbstractRepositoryConfigurationSourceSupport.java:138)
    at org.springframework.data.repository.config.RepositoryConfigurationSourceSupport.lambda$getCandidates$2(RepositoryConfigurationSourceSupport.java:82)

【问题讨论】:

尝试在DemoApplicationTests类上方添加@ExtendWith(SpringExtension.class) 对我不起作用。不过在尝试了几件事后发现了。 【参考方案1】:

我找到了两种方法来实现这一点。一种方法是

@ContextConfiguration(classes = 
  DemoApplication.class,
  DemoApplicationTests.Config.class
)

DemoApplication 加载配置。虽然它通常更干净,但如果您有其他服务,例如 EnableRedisRepositories 和 EnableKafka,测试可能仍然会失败,因为这些资源可能未在您的脚本中配置。

或者,可以启用Config 类,因此只执行 JPA 测试。这是我最终选择的,因为我在从中提取样本的代码上使用了 EnableRedisRepositories。

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories
    @EntityScan
    static class Config

【讨论】:

以上是关于在 JUnit 5 中使用 @TestContainers 实现 @DataJpaTest的主要内容,如果未能解决你的问题,请参考以下文章

Junit 5 如何使用 Guice DI

如何将 JUnit 5 与 Gradle 一起使用?

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

如何在 JUnit 5 中替换 WireMock @Rule 注释?

JUnit 5:如何断言抛出异常?

在 Junit 5 中,如何从扩展中调用测试类方法?