Mockito: How to combine varargs in java 8?

I am working on porting a project from java 7 to 8 and received a compilation error in Mockito "when" in case I find it difficult to track:

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

gives a compilation error:

 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 occurs in version 1.8.0-b128, but this does not happen in version 1.7.0_45. I am using mockito 1.9.5.

What is the correct way to use anyVarArg() argument anyVarArg() in java 8?

+8
java java-8 mockito
source share
1 answer

The problem is that type inference has been improved. anyVararg() is a generic method, but you use it in a nested method call. Before Java 8, type inference restrictions forced the <T> T anyVararg() method to be <Object> Object anyVararg() when placed as an argument to call another method without inserting explicit type arguments.

Thus, only query(String, ResultSetHandler, Object...) , as the third argument, was considered as an Object type.

But now that Java 8 type output works with nested method calls. Since for <T> T anyVararg() parameter of type <T> can be anything, it can be a ResultSetHandler . Thus, query(String,Object,ResultSetHandler) also a candidate candidate.

(I omitted a parameter of type <T> from an external call in both cases to make it less confusing)

Since we have two possible matches, the usual procedure for selecting a method is used here. And yes, this is ambiguous. The first parameter is the same, String , but for the other two ResultSetHandler more specific than Object , but while one candidate takes on a more specific type for the second parameter, the other makes for the third (and subsequent) window).

Clearly, type parameters that allow you to return a method type as anything are a source of ambiguity, but APIs like Mockitos containing such methods are a cornerstone of Java programming. You will have to force the type to be either the generic Matchers.<Desired>anyVararg() , or using the cast (Desired)anyVararg() .

+7
source share

All Articles