Testcontainers初始化后Repository始终为空,如何实现非Mock真实数据测试
Testcontainers集成测试Repository为null解决方案
问题根因梳理
- 测试类未启用Spring Boot测试上下文,
@Autowired无法注入真实的Repository Bean - 错误使用了
@MockBean注解,会直接替换Spring上下文中的真实Repository为Mock对象 - 保留了Mockito初始化逻辑,针对真实Bean场景不需要这套逻辑
- application-test.yml中的JDBC URL格式错误,且Testcontainers容器端口是动态生成的,不能硬编码连接地址
- 父类的MySQL容器未将动态连接参数同步到Spring上下文配置
具体修改方案
1. 修正父类AbstractTestConfiguration配置
增加Spring Boot测试上下文启用注解,添加动态参数注入逻辑,同步容器的连接配置到Spring环境:
@SpringBootTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @Testcontainers public abstract class AbstractTestConfiguration { @Container private MySQLContainer<?> database = new MySQLContainer<>("mysql:8.0") // 可直接指定初始化脚本,替代配置文件中的硬编码配置 .withInitScript("init.sql"); // 把容器动态生成的连接参数注入Spring上下文 @DynamicPropertySource static void setDataSourceProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", database::getJdbcUrl); registry.add("spring.datasource.username", database::getUsername); registry.add("spring.datasource.password", database::getPassword); registry.add("spring.datasource.driver-class-name", database::getDriverClassName); } @Test public void testContainerRunning() { assertTrue(database.isRunning()); } }
2. 修正Repository测试类配置
删除Mock相关注解和逻辑,改用@Autowired注入真实实例:
@Sql("classpath:data.sql") class OrderDataRepositoryTest extends AbstractTestConfiguration { // 注入真实Repository实例 @Autowired private OrderDataRepository orderRepository; @Test void getAllOrdersTest() { List<Order> orders = orderRepository.findAll(); // 补充业务断言即可 assertNotNull(orders); orders.forEach(System.out::println); } }
3. 清理application-test.yml冲突配置
删除硬编码的数据源配置,避免覆盖容器动态生成的连接参数:
spring: application: name: your-application-name # 移除原有硬编码的datasource配置
校验点
确保OrderDataRepository添加了@Repository注解,且所在包在Spring Boot启动类的扫描路径范围内,调整后即可基于真实数据库实例完成测试。
内容的提问来源于stack exchange,提问作者Mike3355
相关产品推荐
相关产品推荐

