如何为使用R2dbcEntityTemplate的PostgreSQL编写JUnit测试
为使用R2dbcEntityTemplate的类编写JUnit测试
针对你的场景,推荐使用Testcontainers启动真实的PostgreSQL容器进行测试(保证和生产环境兼容性),结合Spring Boot的反应式测试工具验证结果,具体步骤如下:
1. 添加测试依赖
以Maven为例,在pom.xml中加入以下测试依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-postgresql</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency>
2. 编写测试类
假设你的业务类名为CustomQueryService,其中包含调用R2dbcEntityTemplate执行自定义SQL的方法(比如executeCustomQuery()),测试类示例如下:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.r2dbc.R2dbcTest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.TestPropertySource; import org.testcontainers.containers.PostgresContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import reactor.test.StepVerifier; // 仅加载R2DBC相关配置,比@SpringBootTest更轻量 @R2dbcTest // 导入待测试的业务类 @Import(CustomQueryService.class) @Testcontainers public class CustomQueryServiceTest { // 启动PostgreSQL容器,指定镜像版本 @Container static PostgresContainer<?> postgresContainer = new PostgresContainer<>("postgres:15-alpine") .withDatabaseName("test_db") .withUsername("test_user") .withPassword("test_pass"); // 动态覆盖R2DBC连接配置,无需手动编写application-test.properties @DynamicPropertySource static void configureR2dbcProperties(DynamicPropertyRegistry registry) { String r2dbcUrl = String.format("r2dbc:postgresql://%s:%d/%s", postgresContainer.getHost(), postgresContainer.getFirstMappedPort(), postgresContainer.getDatabaseName()); registry.add("spring.r2dbc.url", () -> r2dbcUrl); registry.add("spring.r2dbc.username", postgresContainer::getUsername); registry.add("spring.r2dbc.password", postgresContainer::getPassword); } @Autowired private CustomQueryService queryService; @Autowired private DatabaseClient databaseClient; // 测试前初始化数据库表和测试数据 @BeforeEach void setUpTestData() { // 创建测试表 databaseClient.sql("CREATE TABLE IF NOT EXISTS test_table (id SERIAL PRIMARY KEY, name VARCHAR(255))") .fetch() .rowsUpdated() .block(); // 阻塞等待操作完成(仅测试环境使用) // 插入测试数据 databaseClient.sql("INSERT INTO test_table (name) VALUES ('test_data_1'), ('test_data_2')") .fetch() .rowsUpdated() .block(); } @Test void testCustomQueryExecution() { // 调用业务方法获取反应式结果流 var queryResult = queryService.executeCustomQuery(); // 使用StepVerifier验证反应式流的结果 StepVerifier.create(queryResult) .expectNextCount(2) // 预期返回2条数据 .verifyComplete(); // 验证流正常结束 } }
关键说明
- Testcontainers的优势:启动真实的PostgreSQL容器,避免嵌入式数据库与生产环境的兼容性问题,保证测试结果的可信度。
- 反应式测试工具:使用
StepVerifier验证Flux/Mono类型的结果流,这是Spring反应式编程测试的标准方式,能精准验证流的元素数量、内容、异常等场景。 - 环境隔离:
@BeforeEach方法在每次测试前初始化数据库,确保测试之间不会互相干扰。 - 动态配置:通过
@DynamicPropertySource自动从容器获取连接信息,无需手动维护测试环境的配置文件。
如果你的自定义SQL包含参数,可以扩展测试方法,传入不同参数验证返回结果是否符合预期,比如:
@Test void testCustomQueryWithParameter() { var queryResult = queryService.executeCustomQueryWithParam("test_data_1"); StepVerifier.create(queryResult) .expectNextMatches(data -> data.get("name").equals("test_data_1")) .verifyComplete(); }
内容的提问来源于stack exchange,提问作者girijanandan nucha
相关产品推荐
相关产品推荐

