mockito:如何匹配java 8中的varargs?

Pau*_*ald 8 java mockito java-8

我正在努力将一个项目从java 7迁移到8,并且在Mockito"遇到"情况下遇到编译错误我很难追踪到:

when(queryRunner.query(any(String.class), any(ResultSetHandler.class), anyVararg())).thenReturn(mockedWordResultList);
Run Code Online (Sandbox Code Playgroud)

给我一个编译错误:

java: reference to query is ambiguous   both method
<T>query(java.lang.String,java.lang.Object,org.apache.commons.dbutils.ResultSetHandler<T>)
in org.apache.commons.dbutils.QueryRunner and method
<T>query(java.lang.String,org.apache.commons.dbutils.ResultSetHandler<T>,java.lang.Object...)
in org.apache.commons.dbutils.QueryRunner match
Run Code Online (Sandbox Code Playgroud)

在构建1.8.0-b128中发生此错误,但在1.7.0_45中不会发生.我正在使用mockito 1.9.5.

anyVarArg()在java 8中使用参数匹配的正确方法是什么?

Hol*_*ger 7

问题是类型推断已得到改进.anyVararg()是一个通用方法,但您在嵌套方法调用中使用它.在Java 8之前,类型推断的局限性强制处理方法,<T> T anyVararg()就像<Object> Object anyVararg()将其作为参数放置到另一个方法调用而不插入显式类型参数一样.

所以只有query(String, ResultSetHandler, Object...)匹配,因为第三个参数被视为类型Object.

但现在使用Java 8类型推断可以使用嵌套方法调用.因为<T> T anyVararg()类型参数<T>可以是任何东西,它也可以ResultSetHandler.所以query(String,Object,ResultSetHandler)现在也是比赛候选人.

(<T>在两种情况下,我都省略了外部调用的类型参数,以减少它的混乱)

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

很明显,允许方法返回类型的类型参数只是一个模糊性的来源,但像Mockito这样的包含这些方法的API是Java编程的基础案例.您必须以通用方式Matchers.<Desired>anyVararg()或通过类型转换强制类型(Desired)anyVararg().