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

JUnit5单元测试运行报ParameterResolutionException构造器参数解析错误

问题根因
  • JUnit 5 默认不支持测试类构造器参数自动注入,你仅引入了SpringExtension但未加载Spring上下文、未开启测试构造器注入能力,Spring无法识别构造参数对应的Bean,因此抛出ParameterResolutionException。
  • 代码存在多处语法、配置不统一问题:
    1. 业务代码CodeConfigBuilder中重复定义了两次validateRequestAndSetDefaults方法,第二次调用私有方法时错误传入类名而非参数变量
    2. 测试类中PromoRequest拼写错误为PromonRequest,构造器属性赋值时混淆了参数名和类名
    3. 配置key不统一:CodeConfigBuilder注入用的是promoConfig.prefix.length,PropertySourceResolver注入用的是promoGenerationConfig.prefix.length,会导致后续注入失败
修复方案

方案1:启动Spring上下文做集成测试

适合需要验证配置加载、完整服务链路的场景:

  1. 先修复业务代码的语法、配置问题
  • 删除CodeConfigBuilder中重复的方法,修正方法调用逻辑:
@Component
public class CodeConfigBuilder {
    @Value("${promoConfig.prefix.length}")
    private Integer prefixLength;

    public void validateRequestAndSetDefaults(PromoRequest promoRequest) {
        prefixAndPostFixControlAccordingToLength(promoRequest);
    }

    private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest) {
        if (promoRequest.getPostfix() != null) {
            int lengthControl = prefixLength + promoRequest.getPostfix().length();
            if (lengthControl >= promoRequest.getLength()) {
                throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT);
            }
        }
    }
}
  • 统一配置key:将PropertySourceResolver的注入注解改为@Value("${promoConfig.prefix.length}"),和yml配置保持一致
  1. 修正测试类注解和逻辑
@SpringBootTest // 加载Spring完整上下文
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) // 开启测试类构造器自动注入(Spring Boot 2.2+支持)
@ExtendWith(SpringExtension.class)
class CodeConfigBuilderTest {
    private final PromoRequest promoRequest;
    private final PropertySourceResolver propertySourceResolver;
    private final PromoService promoService;
    private final Request request;

    // 修正拼写和属性赋值错误
    public CodeConfigBuilderTest(PromoRequest promoGenerationRequest, PropertySourceResolver propertySourceResolver, PromoService promoService, Request request) {
        this.promoRequest = promoGenerationRequest;
        this.propertySourceResolver = propertySourceResolver;
        this.promoService = promoService;
        this.request = request;
    }

    @Test
    void prefixAndPostFixControlAccordingToLength() {
        // 先设置测试参数,避免空指针
        promoRequest.setPostfix("test");
        promoRequest.setLength(10);
        
        promoService.validateRequest(promoRequest);
        int lengthControl = propertySourceResolver.getPrefixLength() + promoRequest.getPostfix().length();
        Assertions.assertTrue(lengthControl < promoRequest.getLength(), "前后缀长度之和不能大于指定总长度");
    }
}

方案2:轻量单元测试(无需启动Spring上下文)

适合仅测试业务逻辑、不需要验证配置加载的场景,执行效率更高:

@ExtendWith(MockitoExtension.class)
class CodeConfigBuilderTest {
    @InjectMocks
    private CodeConfigBuilder codeConfigBuilder;

    @BeforeEach
    void setUp() {
        // 手动给@Value属性赋值,替代Spring配置注入
        ReflectionTestUtils.setField(codeConfigBuilder, "prefixLength", 3);
    }

    @Test
    void testPrefixPostfixCheck() {
        PromoRequest request = new PromoRequest();
        request.setPostfix("abc");
        request.setLength(10);
        // 直接测试核心逻辑
        Assertions.assertDoesNotThrow(() -> codeConfigBuilder.validateRequestAndSetDefaults(request));
        
        // 测试异常场景
        request.setLength(5);
        BadRequestException exception = Assertions.assertThrows(BadRequestException.class, 
            () -> codeConfigBuilder.validateRequestAndSetDefaults(request));
        Assertions.assertEquals(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT, exception.getMessage());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:24:04