411 Stimmen

So erfassen Sie eine Liste eines bestimmten Typs mit Mockito

Gibt es eine Möglichkeit, eine Liste eines bestimmten Typs mit mockitos ArgumentCaptore zu erfassen. Dies funktioniert nicht:

ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);

10 Stimmen

Ich finde, dass es eine schreckliche Idee ist, hier eine konkrete Listenimplementierung zu verwenden ( ArrayList ). Sie können jederzeit die List Schnittstelle, und wenn Sie die Tatsache darstellen wollen, dass sie kovariant ist, dann können Sie extends : ArgumentCaptor<? extends List<SomeType>>

3voto

quzhi65222714 Punkte 324

Für eine frühere Version von junit können Sie Folgendes tun

Class<Map<String, String>> mapClass = (Class) Map.class;
ArgumentCaptor<Map<String, String>> mapCaptor = ArgumentCaptor.forClass(mapClass);

0 Stimmen

Dies führt lediglich zu einer anderen Warnung bei nicht geprüfter Zuordnung.

1voto

Timofey Orischenko Punkte 1098

Ich hatte das gleiche Problem beim Testen von Aktivitäten in meiner Android-App. Ich verwendete ActivityInstrumentationTestCase2 y MockitoAnnotations.initMocks(this); hat nicht funktioniert. Ich habe dieses Problem mit einer anderen Klasse mit entsprechendem Feld gelöst. Zum Beispiel:

class CaptorHolder {

        @Captor
        ArgumentCaptor<Callback<AuthResponse>> captor;

        public CaptorHolder() {
            MockitoAnnotations.initMocks(this);
        }
    }

Dann, im Aktivitätsprüfverfahren:

HubstaffService hubstaffService = mock(HubstaffService.class);
fragment.setHubstaffService(hubstaffService);

CaptorHolder captorHolder = new CaptorHolder();
ArgumentCaptor<Callback<AuthResponse>> captor = captorHolder.captor;

onView(withId(R.id.signInBtn))
        .perform(click());

verify(hubstaffService).authorize(anyString(), anyString(), captor.capture());
Callback<AuthResponse> callback = captor.getValue();

1voto

Jezor Punkte 2838

Es gibt eine offenes Problem in Mockitos GitHub über genau dieses Problem.

Ich habe eine einfache Lösung gefunden, die Sie nicht zwingt, Anmerkungen in Ihren Tests zu verwenden:

import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;

public final class MockitoCaptorExtensions {

    public static <T> ArgumentCaptor<T> captorFor(final CaptorTypeReference<T> argumentTypeReference) {
        return new CaptorContainer<T>().captor;
    }

    public static <T> ArgumentCaptor<T> captorFor(final Class<T> argumentClass) {
        return ArgumentCaptor.forClass(argumentClass);
    }

    public interface CaptorTypeReference<T> {

        static <T> CaptorTypeReference<T> genericType() {
            return new CaptorTypeReference<T>() {
            };
        }

        default T nullOfGenericType() {
            return null;
        }

    }

    private static final class CaptorContainer<T> {

        @Captor
        private ArgumentCaptor<T> captor;

        private CaptorContainer() {
            MockitoAnnotations.initMocks(this);
        }

    }

}

In diesem Fall erstellen wir eine neue Klasse mit die @Captor Anmerkung und injizieren Sie den Fänger in diese. Dann extrahieren wir einfach den Fänger und geben ihn aus unserer statischen Methode zurück.

In Ihrem Test können Sie es so verwenden:

ArgumentCaptor<Supplier<Set<List<Object>>>> fancyCaptor = captorFor(genericType());

Oder mit einer Syntax, die der von Jackson ähnelt TypeReference :

ArgumentCaptor<Supplier<Set<List<Object>>>> fancyCaptor = captorFor(
    new CaptorTypeReference<Supplier<Set<List<Object>>>>() {
    }
);

Es funktioniert, weil Mockito keine Typinformationen benötigt (im Gegensatz zu Serializern zum Beispiel).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X