如何使用Mockk的verify方法忽略函数入参中的指定属性校验
解决Mockk测试中忽略动态生成属性的参数匹配问题
这个问题很常见——当参数里有动态生成的字段(比如实时时间戳)时,精确匹配对象就会失败。这里有几个靠谱的解决方案帮你搞定Mockk里的这个参数匹配问题:
方法1:使用match自定义匹配逻辑
Mockk的match函数允许你编写自定义的校验逻辑,只关注你关心的属性,完全忽略created这类动态生成的字段:
verify(exactly = 1) { publish(match { data -> data.notificationId == notificationData.notificationId && data.operation == notificationData.operation && data.partnerName == notificationData.partnerName && data.services == notificationData.services // 故意不校验created属性,直接跳过 }) }
这种方式最直接,你可以完全控制哪些属性需要校验,哪些忽略,逻辑清晰易懂。
方法2:使用参数捕获器捕获并校验
如果你还想额外验证created字段是否是合理的时间(比如在当前时间附近),可以用参数捕获器先捕获实际调用的参数,再逐个校验属性:
// 定义一个参数捕获器,用来捕获NotificationData类型的参数 val notificationCaptor = slot<NotificationData>() // 验证publish被调用了1次,同时捕获传入的参数 verify(exactly = 1) { publish(capture(notificationCaptor)) } // 获取捕获到的实际参数 val capturedData = notificationCaptor.captured // 校验核心属性是否匹配 assertEquals(notificationData.notificationId, capturedData.notificationId) assertEquals(notificationData.operation, capturedData.operation) assertEquals(notificationData.partnerName, capturedData.partnerName) assertEquals(notificationData.services, capturedData.services) // 可选:验证created时间是否在合理范围内(比如前后1秒) val currentTime = Instant.now().toEpochMilli() assertThat(capturedData.created.toLong(), isCloseTo(currentTime, 1000))
这种方式不仅能忽略动态字段的精确匹配,还能对动态字段做合理性校验,适合需要确保时间字段逻辑正确的场景。
不推荐的方法:修改equals方法
虽然可以修改NotificationData的equals方法让它忽略created属性,但这种做法会影响整个应用中该类的对象比较逻辑,可能引发其他意想不到的问题,所以一般不建议这么做。
内容的提问来源于stack exchange,提问作者Mayur Jain
相关产品推荐
相关产品推荐

