简体   繁体   English

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

[英]mockito: How to match varargs in java 8?

I'm working on migrating a project from java 7 to 8, and have gotten a compilation error in a Mockito "when" case I'm having a hard time tracking down: 我正在努力将项目从java 7迁移到8,并且在Mockito“遇到”情况下遇到了编译错误我很难追踪到:

when(queryRunner.query(any(String.class), any(ResultSetHandler.class), anyVararg())).thenReturn(mockedWordResultList);

gives me a compilation error of: 给我一个编译错误:

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

This error happens in build 1.8.0-b128, but doesn't happen in 1.7.0_45. 在构建1.8.0-b128中发生此错误,但在1.7.0_45中不会发生。 I'm using mockito 1.9.5. 我正在使用mockito 1.9.5。

What's the correct way to use anyVarArg() argument matching in java 8? 在java 8中使用anyVarArg()参数匹配的正确方法是什么?

The problem is that the type inference has been improved. 问题是类型推断已得到改进。 anyVararg() is a generic method but you are using it in a nested method invocation. anyVararg()是一个泛型方法,但您在嵌套方法调用中使用它。 Before Java 8 the limitations of the type inference forced treating the method <T> T anyVararg() like <Object> Object anyVararg() when placed as an argument to another method invocation without inserting explicit type arguments. 在Java 8之前,类型推断的局限性强制将方法<T> T anyVararg()<Object> Object anyVararg()作为参数放在另一个方法调用中而不插入显式类型参数。

So only query(String, ResultSetHandler, Object...) matched as the third argument was treated as being of type Object . 因此,只有作为第三个参数匹配的query(String, ResultSetHandler, Object...)被视为Object类型。

But now with Java 8 type inference works with nested method calls. 但现在使用Java 8类型推断可以使用嵌套方法调用。 Since for <T> T anyVararg() the type parameter <T> can be just anything , it can be ResultSetHandler as well. 因为对于<T> T anyVararg() ,类型参数<T>可以是任何东西 ,它也可以是ResultSetHandler So query(String,Object,ResultSetHandler) also is a match candidate now. 因此query(String,Object,ResultSetHandler)现在也是匹配候选者。

(I omitted the type parameter <T> from the outer call in both cases to make it less confusing) (在两种情况下,我从外部调用中省略了类型参数<T> ,以减少混淆)

Since we have two possible matches now, the normal procedure of method selection applies here. 由于我们现在有两种可能的匹配,因此这里适用方法选择的正常程序。 And yes, it's ambiguous. 是的,这是模棱两可的。 The first parameter is the same, String , but for the other two ResultSetHandler is more specific than Object but while one candidate accepts a more specific type for the second parameter, the other does for the third (and follow-ups). 第一个参数是相同的String ,但是对于另外两个ResultSetHandlerObject更具体,但是一个候选者接受第二个参数的更具体类型,另一个候选者接受第三个(和后续)。

It's clear that type parameters that allow a method's return type to be just anything are a source of ambiguity but APIs like Mockito's containing such methods are a corner case of Java programming. 很明显,允许方法返回类型的类型参数只是一个模糊性的来源,但像Mockito这样的包含这些方法的API是Java编程的基础案例。 You will have to force a type either the generic way Matchers.<Desired>anyVararg() or via type cast (Desired)anyVararg() . 您必须使用通用方式Matchers.<Desired>anyVararg()或通过类型转换(Desired)anyVararg()类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM