You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 16:05:01