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

如何使用Spock测试Java类并解决RiskProfile构造器匹配报错问题

异常根因

你触发构造器匹配错误的核心原因是参数类型不匹配:

  • RiskProfile 提供的构造器第一个入参要求是 UserId 类型,你在测试代码里直接传入了字符串 "userId",类型完全不符
  • Groovy 运行时会对传入的错误参数做隐式类型转换,最终抛出的提示里的参数列表和你实际传入的不一致,是类型转换后的错误匹配结果
修复方案

你可以直接用 RiskProfile 已经提供的静态create工厂方法来生成实例,不需要手动传入全量构造参数,代码更简洁,也能避免参数写错的问题:

def "should verify user"() {                                  
    given:                                                    
    def testUserIdStr = "12345"
    // 构造合法的UserId实例,这里假设UserId构造器接收字符串ID作为入参
    def testUserId = new UserId(testUserIdStr)

    when:                                                  
    def res = mvc.perform(post(url)                        
            .content(json)                                 
            .contentType(MediaType.APPLICATION_JSON))      
            .andExpect(status().isOk())                    
            .andReturn()                                   
            .response                                      

    then:
    // 如果你要精确匹配入参,就写testUserIdStr,模糊匹配任意字符串可以写 _ as String
    1 * serviceFacade.getRiskProfile(testUserIdStr) >> ServiceFacade.RiskProfile.create(testUserId, Optional.empty())
}

如果你一定要直接调用构造器,正确写法如下:

then:
1 * serviceFacade.getRiskProfile(testUserIdStr) >> new ServiceFacade.RiskProfile(
    testUserId,
    0,
    Instant.now(),
    Optional.empty(),
    Optional.empty()
)
扩展:验证AffordabilityCheck逻辑

如果你需要验证affordabilityCheck存在时的属性填充逻辑,可以构造带模拟对象的实例:

def "should return risk group when affordability check exists"() {
    given:
    def testUserIdStr = "12345"
    def testUserId = new UserId(testUserIdStr)
    // 模拟AffordabilityCheck实例
    def mockAc = Mock(AffordabilityCheck)
    mockAc.getRiskGroup() >> RiskGroup.MEDIUM // 替换为你实际的风险组枚举值

    when:
    def res = mvc.perform(post(url)
            .content(json)
            .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andReturn()
            .response

    then:
    1 * serviceFacade.getRiskProfile(testUserIdStr) >> ServiceFacade.RiskProfile.create(testUserId, Optional.of(mockAc))
    // 还可以加断言验证返回的response里包含RiskGroup属性
    res.contentAsString.contains("RiskGroup")
    res.contentAsString.contains("MEDIUM")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:24:02