Rozważ ten kod:
public class DummyClass {
public List<? extends Number> dummyMethod() {
return new ArrayList<Integer>();
}
}
public class DummyClassTest {
public void testMockitoWithGenerics() {
DummyClass dummyClass = Mockito.mock(DummyClass.class);
List<? extends Number> someList = new ArrayList<Integer>();
Mockito.when(dummyClass.dummyMethod()).thenReturn(someList); //Compiler complains about this
}
}
Kompilator skarży się na wiersz, który próbuje odgiąć zachowanie dummyMethod()
. Jakieś wskazówki, jak obchodzić się z metodami stubbingowymi, które zwracają typ z ograniczonymi symbolami wieloznacznymi?
java
unit-testing
generics
mockito
bounded-wildcard
Shikhar Mishra
źródło
źródło
Odpowiedzi:
W tym celu możesz również skorzystać z bezpiecznej metody doReturn bez typu ,
jak omówiono na grupie Google Mockito.
Chociaż jest to prostsze niż
thenAnswer
, ponownie pamiętaj, że nie jest to bezpieczne. Jeśli obawiasz się o bezpieczeństwo typów, odpowiedź Millhouse jest prawidłowa.Dodatkowe Szczegóły
Dla jasności, oto zaobserwowany błąd kompilatora,
Uważam, że kompilator przypisał pierwszy typ symbolu wieloznacznego podczas
when
wywołania, a następnie nie może potwierdzić, że drugi typ symbolu wieloznacznego wthenReturn
wywołaniu jest taki sam.Wygląda na to,
thenAnswer
że nie występuje ten problem, ponieważ akceptuje typ wieloznaczny, a przyjmuje typthenReturn
inny niż wieloznaczny, który musi zostać przechwycony. Z OngoingStubbing Mockito ,źródło
Zakładam, że chcesz móc załadować
someList
niektóre znane wartości; oto podejście, które wykorzystujeAnswer<T>
razem z metodą pomocniczą opartą na szablonach, aby zapewnić bezpieczeństwo wszystkich typów:źródło
Wczoraj uderzyłem w to samo. Obie odpowiedzi udzielone przez @ nondescript1 i @millhouse pomogły mi znaleźć obejście. Użyłem prawie tego samego kodu co @millhouse, z tą różnicą, że uczyniłem go nieco bardziej ogólnym, ponieważ mój błąd nie był spowodowany przez a
java.util.List
, alecom.google.common.base.Optional
. Moja metoda małego pomocnika pozwala więc na każdy typ,T
a nie tylkoList<T>
:Dzięki tej metodzie pomocniczej możesz napisać:
Kompiluje się dobrze i robi to samo, co
thenReturn(...)
metoda.Czy ktoś wie, czy błąd, który generuje kompilator Javy, to błąd kompilatora, czy też kod jest naprawdę nieprawidłowy?
źródło
Mockito.when(dummyClass.dummyMethod()).thenAnswer(x -> someList)
Ja obracam fikovnik „s komentarz na odpowiedź tutaj, aby nadać mu bardziej widoczne, jak myślę, że jest to najbardziej eleganckie rozwiązanie z użyciem Java 8+.
Dokumentacja Mockito zaleca używanie
doReturn()
(jak sugeruje zaakceptowana odpowiedź) tylko w ostateczności.Zamiast tego, aby ominąć błąd kompilatora opisany w pytaniu, zalecane
when()
podejście Mockito może być użyte zthenAnswer()
i lambdą (zamiast metody pomocniczej):źródło
Chociaż metoda użyteczności zaproponowana przez Marka Radonsky'ego działa, istnieje również inna opcja, która nawet nie wymaga (dziwnie wyglądającego) wyrażenia lambda sugerowanego przez fikovnika:
Jak pokazuje ta odpowiedź na podobne pytanie, możesz również użyć następującego:
źródło