如何在Spring Boot测试SQL脚本中使用配置值?
Spring Boot集成测试中运行带配置占位符的SQL脚本
在Spring Boot集成测试场景中,若需要在测试前执行包含配置占位符的SQL脚本,原生@Sql注解无法解析占位符(如${example.configuration.value}),导致脚本无法正确替换配置值。以下是两种可行的解决方案:
方案1:手动使用ResourceDatabasePopulator(快速实现)
通过ResourceDatabasePopulator加载SQL脚本,并结合Spring的Environment解析占位符,在测试类初始化阶段手动执行脚本。
实现代码
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @SpringBootTest class MyExampleIT { @Autowired private DataSource dataSource; @Autowired private Environment environment; @BeforeAll void loadTestData() throws IOException { // 初始化脚本填充器 ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); // 添加目标SQL脚本 populator.addScript(new ClassPathResource("/test-data-sql/script.sql")); // 关联配置源,用于解析占位符 populator.setPropertySources(new PropertySourcesPropertyResolver(environment.getPropertySources())); // 执行脚本 populator.execute(dataSource); } @Test void testBusinessLogic() { // 编写你的测试逻辑 } }
方案2:自定义注解与TestExecutionListener(优雅复用)
如果多个测试类都需要执行带占位符的SQL脚本,可以通过自定义注解和TestExecutionListener实现复用逻辑。
1. 自定义注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @TestExecutionListeners( listeners = SqlPlaceholderTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS // 保留默认的测试执行监听器 ) public @interface SqlWithPlaceholders { String[] scripts(); // 用于指定脚本路径数组 }
2. 自定义TestExecutionListener
public class SqlPlaceholderTestExecutionListener extends AbstractTestExecutionListener { @Override public void beforeTestClass(TestContext testContext) throws Exception { // 从Spring上下文获取依赖Bean DataSource dataSource = testContext.getApplicationContext().getBean(DataSource.class); Environment environment = testContext.getApplicationContext().getEnvironment(); // 获取自定义注解配置的脚本信息 SqlWithPlaceholders annotation = testContext.getTestClass().getAnnotation(SqlWithPlaceholders.class); if (annotation == null) { return; } // 配置并执行脚本 ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); for (String scriptPath : annotation.scripts()) { populator.addScript(new ClassPathResource(scriptPath)); } populator.setPropertySources(new PropertySourcesPropertyResolver(environment.getPropertySources())); populator.execute(dataSource); } }
3. 使用自定义注解的测试类
@SpringBootTest @SqlWithPlaceholders(scripts = {"classpath:/test-data-sql/script.sql"}) class MyExampleIT { @Test void testBusinessLogic() { // 编写你的测试逻辑 } }
原理说明
原生@Sql注解依赖DefaultSqlScriptExecutor执行脚本,该执行器未集成占位符解析逻辑。而ResourceDatabasePopulator支持通过setPropertySources()方法关联Spring配置源,利用内置的占位符解析机制自动替换脚本中的${...}为配置文件(如application.yml)中的实际值。
内容的提问来源于stack exchange,提问作者mrts
相关产品推荐
相关产品推荐

