升级Spring Boot至2.7.3后出现JUnit参数解析异常及HSQLDB函数问题
Spring Boot 2.6.7 升级到2.7.3后的问题解决
问题1:JUnit 5测试抛出ParameterResolutionException
现象
升级后,com.abc.demo.admin.rest.demoServerABCUserTest测试类运行时抛出org.junit.jupiter.api.extension.ParameterResolutionException,提示无法解析构造函数中的java.lang.String trustStorePassword参数,根因是ApplicationContext加载失败,异常栈如下:
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [java.lang.String trustStorePassword] in constructor [public com.abc.demo.admin.rest.demoServerABCUserTest(java.lang.String,java.lang.String,org.springframework.boot.test.web.client.TestRestTemplate,com.abc.demo.admin.rest.manager.service.ApplicationPropertyService,java.lang.String,java.lang.String)]: Failed to load ApplicationContext at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:239) at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:183) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:74) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:355) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:302) at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:280) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) at java.base/java.util.Optional.orElseGet(Optional.java:369) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
解决步骤
- 定位ApplicationContext加载根因:查看完整异常日志的
Caused by部分,确定真正导致上下文加载失败的原因(比如属性缺失、Bean创建失败、自动配置冲突等)。 - 调整测试参数注入方式:
- 构造函数中的String类型参数(如
trustStorePassword)改用@Value注解注入,避免直接通过构造函数传递,示例:@SpringBootTest public class demoServerABCUserTest { private final String trustStorePassword; private final TestRestTemplate restTemplate; public demoServerABCUserTest(TestRestTemplate restTemplate, @Value("${trust.store.password}") String trustStorePassword) { this.restTemplate = restTemplate; this.trustStorePassword = trustStorePassword; } // 测试方法 } - 确保
@Value对应的属性在测试配置文件(如application-test.properties)中存在。
- 构造函数中的String类型参数(如
- 校验测试注解配置:确认
@SpringBootTest注解配置正确,若需启动web环境,需指定webEnvironment属性:@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
问题2:HSQLDB中PL/pgSQL函数执行失败
现象
升级前在HSQLDB中正常运行的PL/pgSQL函数,升级后无法使用,函数代码如下:
CREATE FUNCTION db_schema.getEmplyoeeReport(deliveryStatus text, limitRecord integer) RETURNS setof db_schema.employee_usage_report_delivery_status AS ' BEGIN RETURN QUERY SELECT * FROM db_schema.employee_usage_report_delivery_status usageDelivery WHERE usageDelivery.status = deliveryStatus LIMIT limitRecord; END; ' LANGUAGE plpgsql
解决步骤
- 适配HSQLDB版本语法:Spring Boot 2.7.3默认使用HSQLDB 2.7.1,相比2.6.7的HSQLDB 2.5.1,对PL/pgSQL语法校验更严格,需修正参数引用方式:
- 方式一:使用位置参数
$1、$2替代参数名CREATE FUNCTION db_schema.getEmplyoeeReport(deliveryStatus text, limitRecord integer) RETURNS setof db_schema.employee_usage_report_delivery_status AS ' BEGIN RETURN QUERY SELECT * FROM db_schema.employee_usage_report_delivery_status usageDelivery WHERE usageDelivery.status = $1 LIMIT $2; END; ' LANGUAGE plpgsql - 方式二:参数名前加冒号标记
CREATE FUNCTION db_schema.getEmplyoeeReport(deliveryStatus text, limitRecord integer) RETURNS setof db_schema.employee_usage_report_delivery_status AS ' BEGIN RETURN QUERY SELECT * FROM db_schema.employee_usage_report_delivery_status usageDelivery WHERE usageDelivery.status = :deliveryStatus LIMIT :limitRecord; END; ' LANGUAGE plpgsql
- 方式一:使用位置参数
- 确认测试环境初始化:确保测试启动时,函数创建脚本能正确执行(可通过
@Sql注解指定初始化脚本),且db_schema模式已正确初始化。
内容的提问来源于stack exchange,提问作者Swapnil
相关产品推荐
相关产品推荐

