2017-03-02 6 views
3

Ich habe eine Android App, an der ich arbeite und versuche, Komponententests dafür zu schreiben. Die App ist mit der MVP-Architektur geschrieben und ich versuche die Presenter-Klasse zu testen.Android: JUnit + Mockito, Test-Rückruf?

Vereinfachte Methode, die ich zu Test ich versucht, sieht wie folgt aus:

public void userPressedButton() { 
    service.loadData(new Callback<Data>{ 
     @Override 
     onResponse(Data data) { 
      view.showData(data); 
     } 
    }); 
} 

Jetzt will ich sicherstellen, dass, wenn die userPressedButton Methode aufgerufen wird view.showData(data) genannt wird.

Ich habe mehrere Ansätze versucht, aber ich kann nicht herausfinden, wie dies zu testen ist.

Irgendwelche Ideen?

Edit: zu klären, ich will

+0

nur um sicher zu sein. Möchten Sie einen Komponententest schreiben?kein intergrationstest –

+0

Maciej Kowalski ja das ist richtig! – JesperQv

Antwort

1

Interessanten Fall eine Einheit Test schreiben.

Was ich tun würde, ist zu:

1) - Erstellen Sie eine konkrete Klasse für dieses bestimmte Rückruf:

public class MyCallback implements Callback<Data>{ 

    private View view; 

    public MyCallback(View view){ 
     this.view = view; 
    } 

    @Override 
    onResponse(Data data) { 
     view.showData(data); 
    } 
} 

Jetzt für diese Klasse Sie einen Komponententest schreiben können, welche ob würde überprüfen Die onResponse-Methode ruft die showData-Methode des view-Felds auf.

2) Nachdem die Umsetzung auf eine konkrete Klasse, aus der Perspektive der Klasse extacted, die die userPressedButton Methode enthält, ist es wirklich nicht wesentlich ist, was in der Callback-Klasse geschieht. Es ist wichtig, dass eine konkrete Umsetzung dieser Schnittstelle übergeben wurde:

public void userPressedButton() { 
    service.loadData(new MyCallback(view)); 
} 

und schließlich den Test:

@InjectMocks 
MyClass myClass; 

@Mock 
Service service; 

@Captor 
ArgumentCaptor argCaptor; 

@Before 
public void init(){ 
    MockitoAnnotations.initMocks(this); 
} 

@Test 
public void shouldUseMyCallback(){ 
    // Arrange 

    // set up myClass for test 

    // Act 
    myClass.userPressedButton(); 

    Mockito.verify(service).loadData(argCaptor.capture()); 

    // Assert 
    assertTrue(argCaptor.getValue instance of MyCallback); 
} 

So prüfen wir, ob die loadData Methode mit der richtigen Implementierung aufgerufen.

Das ist, wie ich Ihren Fall testen würde.

0

Sie könnten „store“ der Rückruf und verwenden Sie einen Test Rückruf während des Tests

class YourClass { 

    private ??? view; 
    private Callback<Data> callback; 

    // for testing purposes 
    protected YouClass(Callback<Data> callback) { 
     this.callback = callback; 
    } 

    public YouClass() { 
     this(new Callback<Data>{ 
      @Override 
      onResponse(Data data) { 
       view.showData(data); 
      } 
     }); 
    } 

    public void userPressedButton() { 
     service.loadData(this.callback); 
    } 
} 

dann einige benutzerdefinierte Rückruf für den Test verwenden

-1

Auch einfachere Lösung. Wenn dies MVP ist, können Sie die Instanz view an die Presenter-Klasse übergeben. Dann testen Sie den Aufruf unter Mock. Diese

ist, was ein Testverfahren aussehen würde:

MVPView view = mock(MVPView.class); 
Presenter presenter = new Presenter(view) 
presenter.userPressedButton(); 
verify(view, atLeastOnce()).showData(any(Data.class)); 

Wenn der Anruf asynchronious ist, dann warten Sie auf das Ergebnis durch die letzte Anweisung ändern:

verify(view, timetout(5000).atLeastOnce()).showData(any(Data.class)); 
+0

Vielen Dank für Ihre Antwort! Funktioniert das auch, wenn die loadData-Methode einen Netzwerkaufruf durchführt? – JesperQv

+0

Dann muss man auch das 'Service'-Verhalten nachahmen. –

Verwandte Themen