2017-05-19 3 views
1

Observable ist die finale Klasse, daher können wir keine Mocks erstellen, um Interaktionen daran zu verifizieren oder zu erfassen.So überprüfen Sie keine Interaktionen auf RxJava2 Observable mit Mockito

Und beobachtbare der test(), TestSubscriber bietet auch keine eine solche Interaktion Behauptung techinque

ich im Cache gespeicherten Daten erstellt haben, ein generisches Verfahren zur Überprüfung vor

/** 
* General parametrized method for loading data from service while checking connection 
* and respecting reload state 
*/ 
private <T> Observable<T> getData(Observable<T> dataSource, String key, boolean reload) { 
    T cachedData = (T) cacheModel.getValue(key); 

    // Do not use cache if reloading 
    if(!reload && cachedData != null) 
     return Observable.just(cachedData); 

    if(!utilModel.isConnected()) { 
     return Observable.error(new Throwable(Constants.NO_NETWORK)); 
    } 

    return dataSource 
     .doOnNext(data -> cacheModel.saveObject(key, data)) 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()); 
} 

von Netzwerk laden Und es wie folgt verwendet:

@Override 
public Observable<User> getOrganiser(boolean reload) { 
    return getData(eventService.getUser(authorization), ORGANIZER, reload); 
} 

Vorher rief ich nicht einmal eventService.getUser(...) an, um das Observable zu bekommen, also konnte ich te st, wenn es nie aufgerufen wurde, aber jetzt, da ich es an die Template-Methode übergeben muss, muss ich es aufrufen, aber überprüfen, ob Cache vorhanden ist, mit der es nie interagiert.

Dies ist mein vorheriger Test, der offenbar jetzt

@Test 
public void shouldLoadOrganizerFromCache() { 
    // Clear cache 
    objectCache.clear(); 

    User user = new User(); 
    objectCache.saveObject(RetrofitEventRepository.ORGANIZER, user); 

    // No force reload ensures use of cache 
    Observable<User> userObservable = retrofitEventModel.getOrganiser(false); 

    userObservable.test().assertNoErrors(); 
    userObservable.test().assertValue(user); 

    verify(eventService, never()).getUser(auth); 
} 

Antwort

1

Unter der Annahme, der beobachtbare Sie testen mögen versagt so etwas wie diese:

Observable<User> userObservable = getData(eventService.getUser(authorization)); 

, während Sie nicht direkt test() Methode verwenden können oder abonnieren Sie mit TestObserver, wie Sie die Eingabe Observable an eine andere Entität übergeben. Sie können Observable Nebeneffektmethoden verwenden, um fast jede Interaktion mit der Observable zu überprüfen.
zum Beispiel in Ihrem Fall können Sie doOnSubscribe verwenden und eine Fahne heben, wenn es genannt wurde (zeigt die Service-Methode aufgerufen wurde, während es sollte nicht als Cache aufgerufen werden soll):

final boolean[] serviceCalled = new boolean[1]; 
Observable<User> userServiceObservable = eventService.getUser(authorization) 
      .doOnSubscribe(disposable -> serviceCalled[0] = true); 

Observable<User> userObservable = getData(userServiceObservable, ORGANIZER, reload); 
userObservable.test() 
     .assertNoErrors() 
     .assertValue(user) 
     .awaitTerminalEvent(); 
Assert.assertEquals(false, serviceCalled[0]); 

BTW, Cache Methode funktioniert möglicherweise nicht wie erwartet, da Sie den Cache beim Erhalten der Observable und nicht beim Abonnieren testen, so kann Cache-Status zum Zeitpunkt der Anmeldung anders sein. auch mehrere Anrufe können gleichzeitig mit mehreren Aufrufen an den Server und die Aktualisierung des Caches passieren, können Sie sehen here mein Vorschlag von Cache mit Observable.defer().

+0

Es wird starr im Laufe der Zeit, um die Interaktionen zu testen, die der Abonnent machen wird, und da ich gerade das Repository und nicht das Repository mit Presenter testet, wird die beobachtbare zurückgegeben nie tatsächlich abonniert, so dass ich nicht testen kann Und vielen Dank für Ihre Cache-Implementierung. Ich habe genau das gesucht, konnte es aber nicht finden. Ich wusste, dass es einen reaktiveren Weg geben würde. – iamareebjamal

Verwandte Themen