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之前,类型推断的局限性强制将方法 T anyVararg()Object anyVararg()作为参数放在另一个方法调用中而不插入显式类型参数。

因此,只有作为第三个参数匹配的query(String, ResultSetHandler, Object...)被视为Object类型。

但现在使用Java 8类型推断可以使用嵌套方法调用。 因为对于 T anyVararg() ,类型参数可以是任何东西 ,它也可以是ResultSetHandler 。 因此query(String,Object,ResultSetHandler)现在也是匹配候选者。

(在两种情况下,我从外部调用中省略了类型参数 ,以减少混淆)

由于我们现在有两种可能的匹配,因此这里适用方法选择的正常程序。 是的,这是模棱两可的。 第一个参数是相同的String ,但是对于另外两个ResultSetHandlerObject更具体,但是一个候选者接受第二个参数的更具体类型,另一个候选者接受第三个(和后续)。

很明显,允许方法返回类型的类型参数只是一个模糊性的来源,但像Mockito包含这些方法的API是Java编程的一个极端情况。 您必须使用通用方式Matchers.anyVararg()或通过类型转换(Desired)anyVararg()类型。