mockito:如何匹配java 8中的varargs?
我正在努力将项目从java 7迁移到8,并且在Mockito中遇到编译错误“在”情况下我很难追踪到:
when(queryRunner.query(any(String.class), any(ResultSetHandler.class), anyVararg())).thenReturn(mockedWordResultList);
给我一个编译错误:
java: reference to query is ambiguous both method query(java.lang.String,java.lang.Object,org.apache.commons.dbutils.ResultSetHandler) in org.apache.commons.dbutils.QueryRunner and method query(java.lang.String,org.apache.commons.dbutils.ResultSetHandler,java.lang.Object...) in org.apache.commons.dbutils.QueryRunner match
在构建1.8.0-b128中发生此错误,但在1.7.0_45中不会发生。 我正在使用mockito 1.9.5。
在java 8中使用anyVarArg()
参数匹配的正确方法是什么?
问题是类型推断已得到改进。 anyVararg()
是一个通用方法,但您在嵌套方法调用中使用它。 在Java 8之前,类型推断的局限性强制将方法
如作为参数放在另一个方法调用中而不插入显式类型参数。
因此,只有作为第三个参数匹配的query(String, ResultSetHandler, Object...)
被视为Object
类型。
但现在使用Java 8类型推断可以使用嵌套方法调用。 因为对于
,类型参数
可以是任何东西 ,它也可以是ResultSetHandler
。 因此query(String,Object,ResultSetHandler)
现在也是匹配候选者。
(在两种情况下,我从外部调用中省略了类型参数
,以减少混淆)
由于我们现在有两种可能的匹配,因此这里适用方法选择的正常程序。 是的,这是模棱两可的。 第一个参数是相同的String
,但是对于另外两个ResultSetHandler
比Object
更具体,但是一个候选者接受第二个参数的更具体类型,另一个候选者接受第三个(和后续)。
很明显,允许方法返回类型的类型参数只是一个模糊性的来源,但像Mockito包含这些方法的API是Java编程的一个极端情况。 您必须使用通用方式Matchers.
或通过类型转换(Desired)anyVararg()
类型。