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
相关产品推荐
相关产品推荐

