Spring Boot:Testcontainers支持

https://docs.spring.io/spring-boot/docs/3.2.0/reference/htmlsingle/#features.testcontainers

除了使用Testcontainers进行集成测试外,还可以在开发时使用它们。

在开发时使用Testcontainers

这种方法允许开发人员快速启动应用程序所依赖的服务的容器,从而无需手动配置数据库服务器等。以这种方式使用Testcontainers提供的功能类似于Docker Compose,只是容器配置在Java中,而不是YAML。

要在开发时使用Testcontainers,你需要使用“测试”类路径而不是“主”类路径来启动应用程序。这将使你能够访问所有声明的测试依赖项,并为你提供编写测试配置的自然位置。

要创建可测试的应用程序版本,你应该在src/test目录中创建一个“Application”类。例如,如果你的主应用程序位于src/main/java/com/example/MyApplication.java中,则应创建src/test/java/com/example/TestMyApplication.java
TestMyApplication类可以使用SpringApplication.from(…)方法来启动真实的应用程序:

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

    public static void main(String[] args) {
        SpringApplication.from(MyApplication::main).run(args);
    }

}

你还需要定义要与应用程序一起启动的容器实例。为此,你需要确保已将spring-boot-testcontainers模块添加为测试依赖项。一旦完成,你可以创建一个@TestConfiguration类,该类声明要启动的容器的@Bean方法。

还可以将@ServiceConnection注解应用于@Bean方法,以创建ConnectionDetails beans。

典型的Testcontainers配置可能如下所示:

import org.testcontainers.containers.Neo4jContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    @ServiceConnection
    public Neo4jContainer<?> neo4jContainer() {
        return new Neo4jContainer<>("neo4j:5");
    }

}

注意Container bean的生命周期由Spring Boot自动管理。容器将自动启动和停止。

提示:可以使用spring.testcontainers.beans.startup属性来更改容器的启动方式。默认情况下,使用sequential 启动,但如果希望并行启动多个容器,也可以选择parallel

定义完测试配置后,可以使用with(…)方法将其附加到测试启动器上:

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

    public static void main(String[] args) {
        SpringApplication.from(MyApplication::main).with(MyContainersConfiguration.class).run(args);
    }

}

现在,可以像启动任何常规的Java主方法应用程序一样启动TestMyApplication,以启动你的应用程序以及运行应用程序所需的容器。

提示:可以使用Maven目标spring-boot:test-run或Gradle任务bootTestRun从命令行执行此操作。

在开发时贡献动态属性

如果想从容器@Bean方法中在开发时贡献动态属性,可以通过注入DynamicPropertyRegistry来实现。这与你在测试中使用的@DynamicPropertySource注解的工作方式类似。它允许添加在容器启动后可用的属性。

典型的配置可能如下所示:

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    public MongoDBContainer mongoDbContainer(DynamicPropertyRegistry properties) {
        MongoDBContainer container = new MongoDBContainer("mongo:5.0");
        properties.add("spring.data.mongodb.host", container::getHost);
        properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
        return container;
    }

}

注意:只要可能,建议使用@ServiceConnection,但是,对于尚未支持@ServiceConnection的技术,动态属性可以作为一种有用的备选方案。

导入Testcontainer声明类

使用Testcontainers时的常见模式是将容器实例声明为静态字段。这些字段通常直接在测试类上定义。它们也可以在父类或测试实现的接口上声明。

例如,下面的MyContainers接口声明了mongoneo4j容器:

import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;

import org.springframework.boot.testcontainers.service.connection.ServiceConnection;

public interface MyContainers {

    @Container
    @ServiceConnection
    MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");

    @Container
    @ServiceConnection
    Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");

}

如果你已经以这种方式定义了容器,或者你只是更喜欢这种风格,则可以导入这些声明类,而不是将容器定义为@Bean方法。为此,将@ImportTestcontainers注解添加到你的测试配置类中:

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.context.ImportTestcontainers;

@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(MyContainers.class)
public class MyContainersConfiguration {

}

提示:如果你不打算使用服务连接功能,但想使用@DynamicPropertySource,请从容器字段中删除@ServiceConnection注解。还可以将带有@DynamicPropertySource注解的方法添加到声明类中。

在开发时使用DevTools与Testcontainers

当使用devtools时,可以使用@RestartScope注解对bean和bean方法进行注解。当devtools重新启动应用程序时,这些bean不会被重新创建。这对于Testcontainer的Container bean特别有用,因为它们可以在应用程序重新启动时保持其状态。

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.devtools.restart.RestartScope;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    @RestartScope
    @ServiceConnection
    public MongoDBContainer mongoDbContainer() {
        return new MongoDBContainer("mongo:5.0");
    }

}

注意:如果你正在使用Gradle并希望使用此功能,则需要将spring-boot-devtools依赖项的配置从developmentOnly更改为testImplementation。使用默认的developmentOnly作用域,bootTestRun任务将无法获取代码中的更改,因为devtools未激活。

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值