2016-11-29 4 views
2

Ich versuche, eine Klasse zu testen, die einen Methodenaufruf macht und von der Antwort durch einen Listener wartet.Mock Callbacks und Listener mit Mockito

Dies sind die Schnittstellen im Interactor. Wenn ich fetch rufe, wird eine der Listener-Funktionen zurückgerufen.

interface Interactor { 
    void fetch(int offset, int size); 
} 

interface InteractorListener { 
    void onReady(List<Result> results); 

    void onError(); 
} 

public class MyInteractor implements Interactor{ 

    private ImageInteractorListener listener; 

    public MyInteractor() {} 

    public onAttach(ImageInteractorListener listener) { 
     this.listener = listener; 
    } 

    public void fetch(int offset, int size) { 
     // Make asyncrhonous task 
     // and manage the response in the next method 
    } 

    public void onAsyncroouTaskResponse() { 
     if (someChecks) { 
      listener.onReady(List<Result> results); 
     } else { 
      listener.onError(); 
     } 
    } 
} 

public class MyClass implements ImageInteractorListener { 

    public MyClass() { 
     MyInteractor interactor = new Interactor(); 
     interactor.onAttach(this); 
     interactor.fetch(1,1); 
    } 

    @Override 
    void onReady(List<Result> results) { 
     // doThings 
    } 

    @override 
    void onError() { 
     // doThings 
    } 
} 

So wird mein Unterricht gemacht. Ich muss MyClass testen, also muss ich Interactor Rückruf spotten

Ich habe verschiedene Lösungen mit verschiedenen Problemen ausprobiert, so habe ich jetzt gerade keinen endgültigen Code oder Fehler. Aber niemand funktioniert ..

Vielen Dank.

+0

Ich bin mir nicht sicher, ob ich Ihre Klassenhierarchie verstehe. Du hast eine "Klasse", die 'fetch' auf einem' Interactor' aufruft. Dieser 'Interactor' hat ein Mitglied mit dem Typ 'InteractorListener' und Sie möchten überprüfen, ob' onReady' oder' onError' in diesem Member aufgerufen werden, nachdem fetch aufgerufen wurde? –

+0

Ich habe Beispielcode hinzugefügt. Vielen Dank! – adalPaRi

Antwort

1

Unter der Annahme, dass Sie MyClass sind Testen können Sie nur manuell Rückruf rufen

// Test that errors are handled 

// Given 
Interactor interactor = mock(Interactor.class); 
MyClass myClass = new MyClass(interactor); 

// When 
interactor.fetch(0, 0); // this call is optional, I just added it for clarity 
myClass.onError(); 

// Then 
// verify something 
+0

Genau - wenn 'MyClass' die Klasse ist, die getestet wird, darfst du * sie nicht verspotten (sonst macht der Test keinen Sinn). –

+0

Aber in Ihrem Beispiel verspotten Sie MyClass, das gerade getestet wird. – adalPaRi

+3

In meinem Beispiel verspotte ich nur 'Interactor'. 'MyClass' wird nicht verspottet. –

1

Dimitry Ansatz ist gut, ich persönlich würde nicht nennen holen, da Ihr onAsyncroouTaskResponse() ist öffentlich, ich nennen würde und dann verify(yourmock).onError() oder ähnlich, um sicherzustellen, dass es aufgerufen wurde.

Ein anderer Ansatz, den ich manchmal mache, ist ein "TestableSubject" zu erstellen, das nur eine class extends YourOriginalClass ist, in der Sie bestimmte Methoden überschreiben und die Anzahl der Aufrufe beibehalten. Manchmal, aufgrund der Natur einiger Klassen, kann man sie nicht alle verspotten (finales, abstraktes Zeug, privat usw.).

Wenn Sie wollen (und vielleicht sollten) testen, dass nach Abschluss Ihrer asynchronen Aufgabe, Ihr Callback aufgerufen wird (unabhängig vom Ergebnis), dann würde ich den Fetch-Teil überspringen, können Sie das Fetch Brände testen der Job in einem anderen Test, aber ich denke, dass Sie sich mehr für den späteren Teil interessieren.

Verwandte Themen