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

SpringBoot测试中如何从application.yml获取数据源实例化groovy.sql.Sql

解决方案:Spock测试中从Spring Boot配置获取数据源属性实例化groovy.sql.Sql

首先,咱们先定位问题根源:你遇到的NullPointerException是因为测试时Spring上下文没有正确加载test/resources/application.yml里的数据源配置,或者你的测试类没有正确注入这些配置属性。下面是具体的解决步骤和示例代码:

1. 确保测试上下文正确加载Spring配置

首先检查你的BaseSpringBootTestSpec基类,必须确保它能触发Spring Boot的上下文加载,尤其是子模块场景下,可能需要明确指定配置类:

import org.springframework.boot.test.context.SpringBootTest
import spock.lang.Specification

// 子模块场景下,明确指定Repository配置类,让Spring扫描到相关Bean和配置
@SpringBootTest(classes = [RepositoryConfig.class])
abstract class BaseSpringBootTestSpec extends Specification {
}

如果你的RepositoryConfig已经包含了数据源和JdbcTemplate的配置(比如带有@Configuration注解,并且定义了DataSource Bean),这个注解会自动加载test/resources/application.yml里的配置。

2. 两种方式实例化groovy.sql.Sql

方式一:直接注入数据源属性

通过@Value注解把yml里的数据源属性注入到测试类,然后用这些属性创建Sql实例:

import groovy.sql.Sql
import org.springframework.beans.factory.annotation.Value
import spock.lang.Subject

class YourRepositorySpec extends BaseSpringBootTestSpec {

    // 从application.yml注入对应配置属性
    @Value("${spring.datasource.url}")
    private String dbUrl

    @Value("${spring.datasource.username}")
    private String dbUsername

    @Value("${spring.datasource.password}")
    private String dbPassword

    @Value("${spring.datasource.driver-class-name}")
    private String dbDriver

    private Sql sql

    // 测试前初始化Sql实例
    def setup() {
        sql = Sql.newInstance(dbUrl, dbUsername, dbPassword, dbDriver)
    }

    // 测试后关闭资源,避免连接泄漏
    def cleanup() {
        sql?.close()
    }

    // 编写你的测试用例
    def "test database query with groovy sql"() {
        when:
        def result = sql.firstRow("SELECT COUNT(*) FROM your_table")

        then:
        result[0] >= 0
    }
}

方式二:注入Spring管理的DataSource(更推荐)

既然Spring已经帮你管理了DataSource Bean,直接注入它,然后从连接创建Sql实例,这样不用手动处理所有属性,更简洁且不易出错:

import groovy.sql.Sql
import javax.sql.DataSource
import org.springframework.beans.factory.annotation.Autowired

class YourRepositorySpec extends BaseSpringBootTestSpec {

    @Autowired
    private DataSource dataSource

    private Sql sql

    def setup() {
        // 从Spring管理的DataSource获取连接创建Sql
        sql = new Sql(dataSource.connection)
    }

    def cleanup() {
        sql?.close()
    }

    // 测试用例示例
    def "test repository data insertion"() {
        given:
        def testData = [name: "spock_test"]

        when:
        sql.insert("INSERT INTO your_table(name) VALUES(?)", testData.name)
        def insertedRecord = sql.firstRow("SELECT * FROM your_table WHERE name = ?", testData.name)

        then:
        insertedRecord.name == testData.name

        cleanup:
        // 测试后清理测试数据,避免污染环境
        sql.execute("DELETE FROM your_table WHERE name = ?", testData.name)
    }
}

3. 排查常见配置问题

  • 检查application.yml格式:确保test/resources/application.yml里的数据源配置没有拼写错误,示例格式如下:
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/your_test_db
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: test_user
        password: test_pass
    
  • 检查测试依赖:确保子模块的pom.xml里引入了必要的测试依赖:
    <dependencies>
        <!-- Spring Boot JDBC 核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- Spring Boot 测试依赖 + Spock Spring 整合 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 数据库驱动,根据你的数据库类型调整 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    
  • 检查RepositoryConfig配置类:确保你的配置类带有@Configuration注解,并且正确绑定yml配置,示例如下:
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.core.JdbcTemplate;
    import javax.sql.DataSource;
    import com.zaxxer.hikari.HikariDataSource;
    
    @Configuration
    public class RepositoryConfig {
    
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource dataSource() {
            return new HikariDataSource();
        }
    
        @Bean
        public JdbcTemplate jdbcTemplate(DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }
    }
    

这样调整后,你的测试类应该就能正确获取到数据源配置,实例化groovy.sql.Sql并执行数据库测试了。

内容的提问来源于stack exchange,提问作者victorio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:37