Czy istnieje sposób na przechwycenie listy określonego typu przy użyciu mockitos ArgumentCaptore. To nie działa:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
java
unit-testing
junit
mockito
Andreas Köberle
źródło
źródło
ArrayList
) jest okropnym pomysłem . Zawsze możesz użyćList
interfejsu, a jeśli chcesz przedstawić fakt, że jest on kowariantny, możesz użyćextends
:ArgumentCaptor<? extends List<SomeType>>
Odpowiedzi:
Zagnieżdżonego problemu rodzajowego można uniknąć za pomocą adnotacji @Captor :
źródło
MockitoAnnotations.initMocks(this)
w@Before
sposób niż za pomocą gońca, który wyłącza zdolność do użytkowania innego biegacza. Jednak +1, dziękuję za wskazanie adnotacji.Tak, jest to ogólny problem ogólny, nie związany z mockito.
Nie ma obiektu klasy
ArrayList<SomeType>
, a zatem nie można bezpiecznie wpisać takiego obiektu do metody wymagającejClass<ArrayList<SomeType>>
.Możesz rzucić obiekt na odpowiedni typ:
To da pewne ostrzeżenia o niebezpiecznych rzutach i oczywiście twój ArgumentCaptor nie może tak naprawdę rozróżniać między elementami
ArrayList<SomeType>
iArrayList<AnotherType>
nie sprawdzać ich.(Jak wspomniano w drugiej odpowiedzi, chociaż jest to ogólny problem ogólny, istnieje specyficzne dla Mockito rozwiązanie problemu bezpieczeństwa typu z
@Captor
adnotacją. Wciąż nie można odróżnić anArrayList<SomeType>
iArrayList<OtherType>
.)Edytować:
Zobacz także komentarz tenshi . Możesz zmienić oryginalny kod z Paŭlo Ebermann na ten (znacznie prostszy)
źródło
ArgumentCaptor<List<SimeType>> argument = ArgumentCaptor.forClass((Class) List.class);
@SuppressWarnings("unchecked")
adnotacji nad linią definicji captor argumentu. Ponadto przesyłanie doClass
jest zbędne.Class
nie jest zbędne w moich testach.Jeśli nie boisz się starej semantyki w stylu java (nie typowa bezpieczna generyczna), to również działa i jest dość proste:
źródło
źródło
W oparciu o komentarze @ tenshi i @ pkalinow (również kudos do @rogerdpack), poniższe jest proste rozwiązanie do tworzenia modułu przechwytującego argument listy, który również wyłącza ostrzeżenie „używa operacji niesprawdzonych lub niebezpiecznych” :
Pełny przykład tutaj i odpowiadająca mu wersja kompilacji CI i uruchomienie testowe tutaj .
Nasz zespół używa tego od jakiegoś czasu w naszych testach jednostkowych i wydaje się to dla nas najprostszym rozwiązaniem.
źródło
W przypadku wcześniejszej wersji programu junit możesz to zrobić
źródło
Miałem ten sam problem z testowaniem aktywności w mojej aplikacji na Androida. Użyłem
ActivityInstrumentationTestCase2
iMockitoAnnotations.initMocks(this);
nie działałem. Rozwiązałem ten problem z inną klasą, odpowiednio z polem. Na przykład:Następnie w metodzie testu aktywności:
źródło
W GitHub Mockito istnieje otwarty problem dotyczący tego konkretnego problemu.
Znalazłem proste obejście, które nie zmusza cię do używania adnotacji w swoich testach:
Co się dzieje, jest to, że możemy stworzyć nową klasę z tej
@Captor
adnotacji i wstrzyknąć captor do niego. Następnie po prostu wydobywamy porywacz i zwracamy go z naszej metody statycznej.W teście możesz użyć go w następujący sposób:
Lub ze składnią podobną do Jacksona
TypeReference
:Działa, ponieważ Mockito tak naprawdę nie potrzebuje żadnych informacji o typie (na przykład w przeciwieństwie do serializatorów).
źródło