2014-07-10 18 views
10

Po przełączeniu na język Java 1.8. JDK niektóre z moich klas testowych nie mogą się skompilować. Przykład klasie realizacji:Java 1.8 z Mockito 1.9.5 daje błędy kompilacji

import java.util.concurrent.Callable; 
import java.util.concurrent.Future; 

public class ImplClass { 

    public <T> Future<T> executeTask(final Callable<T> task) { 
     return null; 
    } 
} 

I tu jest klasa Test z Mockito:

import static org.mockito.Matchers.any; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

import java.util.concurrent.Callable; 

import org.junit.Before; 

public class TestClass { 

    private ImplClass implClassMock; 

    @Before 
    public void setUp() { 
     implClassMock = mock(ImplClass.class); 
     when(implClassMock.executeTask(any(Callable.class))).thenReturn(null); 
    } 
} 

otrzymuję komunikat o błędzie: The method executeTask(Callable<T>) in the type ImplClass is not applicable for the arguments (Callable)

Przełączanie z powrotem do Javy kompilatora 1.7 wszystko jest w porządku.

Każdy pomysł, jak rozwiązać ten problem?

+0

Dlaczego klasa ImplClass powinna być ogólna? – Juergen

Odpowiedz

11

Od wersji java 8, wersja compiler type inference została znacznie ulepszona.

Teraz można usunąć parametr klasy z dopasowującego bez żadnego ostrzeżenia kompilacji:

when(implClassMock.executeTask(any())).thenReturn(null); 

Uwaga: mam ten sam błąd kompilatora, ale tylko z zaćmienia. Może być błąd?

+0

Wygląda na to, że rzeczywiście tak jest, 'javac' kompiluje to dobrze. Jeszcze nie potwierdziłem tego na Eclipse, ale nie po raz pierwszy widziałem błędy w kompilatorze Eclipse, daleko od niego ... Teraz tylko ufam 'javac' – Brice

+0

Dziękuję! Zapomniałem wspomnieć, że używam zaćmienia. – Juergen

+1

To jest https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334 Błąd został poprawiony w JDT 4.4. Eclipse Mars 4.5 –

8

Wygląda na to, że javac jest bardziej elastyczny niż wymaga tego JLS. Kompilator Eclipse z poziomem zgodności 1.8 jest bardziej rygorystyczny: https://bugs.eclipse.org/bugs/show_bug.cgi?id=430987

Odpowiedź @gontarda działa w większości przypadków, ale jeśli metoda, którą upynchronizujesz ma nadpisanie z różnymi typami parametrów, javac zostanie zdezorientowany. Na przykład ExecutorService.submit() przyjmuje zarówno parametry Callable, jak i Runnable jako parametry, nie można ich kpić z when (executor.submit (any())). Then then (...) ponieważ jest niejednoznaczny. Ale jawne parametryzowanie tego typu sprawi, że kompilatory Eclipse i javac będą zadowolone: ​​

when(executor.<Object>submit(any(Callable.class)).then(...) 
+1

Kompilator AspectJ ma ten sam problem. Pracowałem nad nim przez dodanie rzutowania: 'when (executorService.submit ((Callable ) any (Callable.class))). ThenReturn (przyszłość);' –

Powiązane problemy