Mockito.any () przekazuje interfejs z rodzajami generycznymi

170

czy możliwe jest przekazanie typu interfejsu za pomocą typów generycznych?

Interfejs:

public interface AsyncCallback<T>

W mojej metodzie testowej:

Mockito.any(AsyncCallback.class)

Odkładanie <ResponseX>za lub za .classwykonaną pracę.

lrxw
źródło

Odpowiedzi:

306

Istnieje sposób bezpieczny dla typu: użyj ArgumentMatchers.any()i zakwalifikuj go za pomocą typu:

ArgumentMatchers.<AsyncCallback<ResponseX>>any()
thSoft
źródło
4
Potwierdzam, że ta odpowiedź działa i poprawnie usuwa ostrzeżenie.
kevinarpe
1
Nie jest to naprawdę bezpieczniejsze, ponieważ rzeczywistą metodę i tak można wywołać tylko z poprawnie wpisanym argumentem. Trzeba było tylko spełnić wymagania kompilatora pre-java8, który nie miał tego rodzaju wnioskowania o typie.
herman
Użyłem czegoś takiego jak ResponseEntity <List <Map <String, Object >>> responseEntity = Matchers. <ResponseEntity <List <Map <String, Object >>>> any (); I zawsze zwraca wartość null
Arun
6
Z nowymi wersjami Mockito:(Matchers.<AsyncCallback<ResponseX>>any()
pierrefevrier
15
Matchersjest faktycznie przestarzały, ale ArgumentMatcherszadziałał.
guijob
67

Korzystając z języka Java 8, możesz po prostu użyć any()(zakładając import statyczny) bez argumentu lub parametru typu ze względu na ulepszone wnioskowanie o typie. Kompilator wie teraz na podstawie typu docelowego (typ argumentu metody), który faktycznie masz na myśli Matchers.<AsyncCallback<ResponseX>>any(), czyli rozwiązanie sprzed wersji Java 8.

Hermana
źródło
Nie any()pasowałby AsyncCallback<AnyOtherType>również?
Matthew Przeczytaj
@MatthewRead Używanie AsyncCallback<AnyOtherType>nie powinno się nawet kompilować, jeśli typ argumentu to „AsyncCallback <ResponseX>”.
herman
1
Zastanawiam się nad sytuacją, w której typ argumentu jest również ogólny, ale chcesz go tylko kpić dla jednego konkretnego typu (lub na różne sposoby kpić z niego dla wielu typów). Podano when(x.y(any())).thenAnswer(...)na przykład, gdzie yjest public <T> T y(AsyncCallback<T> arg). Może lepiej byłoby sprawdzić typ odpowiedzi, jeśli to jest potrzebne?
Matthew Przeczytaj
2
@MatthewRead Ze względu na wymazanie rzeczywistego typu nie można sprawdzić w czasie wykonywania przez Mockito. Więc nie możesz nawet użyć isA(). Jeśli obiekt zawiera Classobiekt odpowiadający typowi, a interfejs to ujawnia, myślę, że możesz to sprawdzić w niestandardowym dopasowywaniu. Lub na przykład w przypadku Collectionmożesz sprawdzić rodzaj elementów.
herman
1
Matcherszostał zastąpiony ArgumentMatchersw Mockito v2
bheussler
15

Musiałem przyjąć następujący mechanizm, aby umożliwić stosowanie leków generycznych:

import static org.mockito.Matchers.any;
List<String> list = any();
when(callMyMethod.getResult(list)).thenReturn(myResultString);

Mam nadzieję, że to komuś pomoże.

theINtoy
źródło
3
Zobacz moją odpowiedź: nie jest to już konieczne w przypadku Javy 8.
herman
5

Zamieszczanie bardziej szczegółowego komentarza jako odpowiedzi, który może być przydatny, jeśli jest obecny w odpowiedzi zamiast w komentarzach.

Z nowymi wersjami Mockito: (Matchers.<AsyncCallback<ResponseX>>any()

zwis
źródło
1
dodałem swój komentarz do oryginalnej odpowiedzi
Joergi
2

W związku z odpowiedzią thSoft umieszczenie wywołania kwalifikowanego do metody any () w metodzie oznaczało, że mogłem usunąć kwalifikację, ponieważ typ zwracany umożliwia wnioskowanie:

private HashMap<String, String> anyStringStringHashMap() {
    return Matchers.any();
}
JWGS
źródło
0

Możesz go po prostu przesłać, dodając pomijane ostrzeżenia, jeśli chcesz:

@SuppressWarnings("unchecked")    
AsyncCallback<ResponseX> callback = Mockito.any(AsyncCallback.class)

Gdyby Java zezwoliła na „generyczne” typy generyczne, mogłaby mieć metodę taką, jak ta, której szukasz

private static <T, E> T<E> mock(Class<T<E>> clazz)
Garrett Hall
źródło
Kiedy próbowałem tego, otrzymałem błąd w moim teście:You cannot use argument matchers outside of verification or stubbing.
kevinarpe
Nie jest to dobry pomysł w użyciu @SuppressWarnings: pre-java 8, jeśli zamierzasz przypisać go do oddzielnej zmiennej, możesz po prostu użyć odpowiedzi any()tak, jak w odpowiedzi INtoy. Teraz z java 8 any()może być używany inline bez potrzeby oddzielnego przypisania.
herman
@kevinarpe, jeśli masz wiele dopasowań argumentów, należy je wywołać w kolejności określonej w języku Java.
TWiStErRob
0

Miałem podobny problem podczas używania Springa Example:

Mockito.when(repo.findAll(Mockito.<Example<SrvReqToSupplierComment>>any()))
            .thenReturn(Lists.emptyList());

Tutaj musisz użyć kwalifikacji, b / c metoda findAll może przyjmować wiele typów, takich jak Sorti Iterable. Możesz również Mockito.any(Example.class)oczywiście użyć z ostrzeżeniem bezpieczeństwa typu.

gagarwa
źródło