Kotlin Spring Test中jsonPath的hasSize断言编译报错解决方案
报错原因
Kotlin的类型推断规则比Java更严格,Spring MockMvc提供的jsonPath方法结合Hamcrest的hasSize、hasItem等带泛型的Matcher使用时,编译器无法自动推断出Matcher对应的目标类型,因此会抛出Not enough information to infer type variable T错误。
解决方法
核心是主动给编译器提供泛型类型信息,常用两种实现方案:
方案1:显式指定jsonPath的返回类型
这是最常用的方案,直接在jsonPath方法上声明返回值的泛型类型即可:
- 如果仅校验集合长度,不关心集合元素类型,指定为
Iterable<*>即可 - 如果需要校验集合内的元素内容,指定为对应元素类型的
Iterable即可
修复后的完整代码示例:
mockMvc!!.perform(get("/api/customer/{id}", customer.id)) .andExpect(status().isOk) .andExpect(jsonPath("$.name", equalTo(customer.name))) .andExpect(jsonPath("$.idNumber", equalTo(customer.idNumber))) .andExpect(jsonPath<Iterable<*>>("$.address", hasSize(0))) .andExpect(jsonPath<Iterable<*>>("$.contact", hasSize(0))) .andExpect(jsonPath<Iterable<String>>("$.address", hasItem("item")))
方案2:显式指定Matcher的泛型类型
也可以直接给hasSize、hasItem等Matcher声明泛型,同样可以解决类型推断问题:
mockMvc!!.perform(get("/api/customer/{id}", customer.id)) .andExpect(status().isOk) .andExpect(jsonPath("$.name", equalTo(customer.name))) .andExpect(jsonPath("$.idNumber", equalTo(customer.idNumber))) .andExpect(jsonPath("$.address", hasSize<Any>(0))) .andExpect(jsonPath("$.contact", hasSize<Any>(0))) .andExpect(jsonPath("$.address", hasItem<String>("item")))
如果项目中大量使用类似断言,可使用Spring官方提供的Kotlin Test扩展,直接调用封装好的jsonPath扩展方法,不需要手动处理泛型,写法更简洁:
// 引入扩展后写法 mockMvc!!.perform(get("/api/customer/{id}", customer.id)) .andExpect { status { isOk() } jsonPath("$.name") { value(customer.name) } jsonPath("$.idNumber") { value(customer.idNumber) } jsonPath("$.address") { hasSize(0) } jsonPath("$.contact") { hasSize(0) } jsonPath("$.address") { hasItem("item") } }
内容的提问来源于stack exchange,提问作者Giovanni Silva
相关产品推荐
相关产品推荐

