Gleeb
Gleeb

Reputation: 11289

Mockito Java 8 compilation errors

I just moved to Java 8 and I am getting some compilation errors that I don't really understand how to overcome.

The following code does not compile:

Mockito.when(
    jdbcTemplate.query(Mockito.eq(expectedQuery1),
        Mockito.any(ResultSetExtractor.class))).thenReturn(mockReturn1);

With error:

The method query(String, ResultSetExtractor<T>) in the type JdbcTemplate is not 
applicable for the arguments (String, ResultSetExtractor)

I have tried another approach from Java 1.8 with Mockito 1.9.5 gives compile errors:

Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1), Mockito.any()))
    .thenReturn(mockReturn1);

now I am getting the following error:

The method when(T) in the type Mockito is not applicable for the arguments (void)

how exactly does this supposed to work and why doesn't it work in the first place

Upvotes: 2

Views: 2747

Answers (2)

Duncan Jones
Duncan Jones

Reputation: 69389

Add a type witness to help the Eclipse compiler figure it all out:

Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1),
        Mockito.<ResultSetExtractor<TYPE>> any())).thenReturn(mockReturn1);

Ensure you replace TYPE with the type of mockReturn1. E.g.

String mockReturn1 = "result";

Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1),
        Mockito.<ResultSetExtractor<String>> any())).thenReturn(mockReturn1);

I expect the Oracle Java 8 compiler could figure this out itself, due to its improved type inference capabilities.

Upvotes: 4

Mike Nakis
Mike Nakis

Reputation: 62054

What is happening is that you are passing mockito ResultSetExtractor.class, which is of type Class<ResultSetExtractor>, but this is incorrect, because it is expecting a Class<ResultSetExtractor<T>>.

To overcome this problem, define a method as follows:

@SuppressWarnings( "rawtypes" )
public static <T> Class<T> uncheckedClassCast( Class clazz )
{
    if( clazz == null )
        return null;
    @SuppressWarnings( "unchecked" )
    Class<T> result = (Class<T>)clazz;
    return result;
}

And use it as follows:

Class<ResultSetExtractor<T>> resultSetExtractorClass =
    uncheckedClassCast( ResultSetExtractor.class );

Then, in your calls to mockito (or anything else) use resultSetExtractorClass instead of ResultSetExtractor.class.

Upvotes: 0

Related Questions