Mockito/Scala中如何正确验证含传名、可变、隐式参数的方法调用
核心问题原因
- 传名参数类型擦除:Scala 中
=> String类型的传名参数编译后会被擦除为Function0[String],无法直接用字符串类型的匹配器或捕获器匹配。 - 可变参数匹配规则:原生 Java Mockito 匹配 Scala 变长参数
(String, String)*时,不能使用any[Seq[...]],必须使用anyVararg()匹配。 - 全参数匹配要求:使用 Mockito 匹配器时,方法的所有参数位置都必须使用匹配器,不能混合传入原始值,否则会报匹配器数量不匹配错误。
正确验证写法
需捕获第一个传名参数值的场景
import org.mockito.ArgumentCaptor import org.mockito.Mockito._ import scala.Function0 // 声明Function0[String]类型的捕获器,匹配擦除后的传名参数类型 val function0Captor = ArgumentCaptor.forClass(classOf[Function0[String]]) // 三个参数位置全部使用匹配器 verify(mock).foo( function0Captor.capture(), anyVararg[(String, String)]() )(any[Context]) // 调用捕获到的Function0的apply方法,获取传名参数实际执行后的值 val actualParam1 = function0Captor.getValue.apply() assert(actualParam1 == "bar")
无需捕获参数,仅验证调用的场景
verify(mock).foo(any[Function0[String]], anyVararg[(String, String)])(any[Context])
错误写法原因说明
- 之前使用
stringCaptor.capture()匹配传名参数时,类型不匹配,相当于该位置没有正确登记匹配器,导致匹配器计数异常。 - 使用
any[Seq[(String, String)]]匹配可变参数不符合Java Mockito的变长参数匹配规则,会触发编译重载匹配失败。
内容的提问来源于stack exchange,提问作者Sean Patrick Floyd
相关产品推荐
相关产品推荐

