如何使用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
相关产品推荐
相关产品推荐

