Ich verwende die MVP-Architektur und möchte JVM-Komponententests durchführen.JVM-Unit-Test mit Mockito zum Testen von Retrofit2 und RxJava für Netzwerkanfragen
In meinem Modell verwende ich Retrofit2 und RxJava, um Filme von einer API zu holen. Ich möchte die Funktion testen getPopularMovies(...)
Diese Funktion wird jedoch einen Aufruf an den Webserver vornehmen. Im Test möchte ich das jedoch irgendwie nachspielen und nur die onSuccess()
und onFailure()
Methoden testen.
Meine Modellklasse sieht aus wie dieser Snippet es kurz zu halten:
public class MovieListModelImp implements MovieListModelContract {
@Override
public void getPopularMovies(PopularMovieResultsListener popularMovieResultsListener) {
mSubscription = mMovieAPIService.getPopular(Constants.MOVIES_API_KEY)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Results>() {
@Override
public void onCompleted() {
Timber.d("onCompleted");
}
@Override
public void onError(Throwable e) {
Timber.e(e, "onError");
popularMovieResultsListener.onFailure(e.getMessage());
}
@Override
public void onNext(Results results) {
Timber.d("onNext %d", results.getResults().size());
popularMovieResultsListener.onSuccess(results);
}
});
}
}
und die Schnittstelle:
public interface MovieListModelContract {
interface PopularMovieResultsListener {
void onFailure(String errorMessage);
void onSuccess(Results popularMovies);
}
void getPopularMovies(PopularMovieResultsListener popularMovieResultsListener);
}
Mein Problem, das ich zu lösen versuche, ist, wie kann ich Mockito verwenden zu testen die getPopularMovies
ohne tatsächlich den Netzwerkdienst anzurufen? Ich will nur, dass testen: popularMoviesResultsListener.onFailure(e.getMessage())
wird bei einem Fehler genannt werden, um Filme zu bekommen und popularMovieResultsListener.onSuccess(results);
auf Erfolg bezeichnet werden, wenn Filme
empfangen werden habe ich einen Test wie diesen, aber ich bin nicht sicher, ob dies richtig ist:
@Test
public void shouldDisplaySuccessWhenNetworkSucceeds() {
/* Results is the movie results class that is returned */
Results results = new Results();
/* Mock the listener */
MovieListModelContract.PopularMovieResultsListener mockPopularMoviesResultsListener =
Mockito.mock(MovieListModelContract.PopularMovieResultsListener.class);
/* Real instance of the model */
MovieListModelImp movieListModelImp = new MovieListModelImp();
/* Call getPopularMovies with mock listener - However, this will still make a real network request */
movieListModelImp.getPopularMovies(mockPopularMoviesResultsListener);
/* Verify - but I think I have got this all wrong */
verify(mockPopularMoviesResultsListener, times(1)).onSuccess(results);
}
Also mein Problem ist, wie kann ich einen Anruf zu einer Netzwerkanfrage und testen Sie die erwartete onSuccess() und onFailure() korrekt funktioniert verspotten?
Ich glaube nicht, dass Sie die echte Netzwerkanforderung verspottet haben, wie es für den Unit-Test Ihrer Klasse erforderlich ist. Ich versuchte, dies in meiner Antwort zu adressieren :) –
@PravinSonawane Das war mein Fehler. Ich habe das falsche Code-Snippet für den Test eingefügt. Ich habe jetzt meine Antwort aktualisiert. Hier verwende ich das when (...). ThenReturn. So verspotten Sie MovieAPIService.getPopular (..), um die korrekten Ergebnisse zurückzugeben. Dann vergewissere ich mich, dass die richtige onFailure() und onSuccess() die richtige Anzahl von Mal aufgerufen wurden. Dies testet nur die Geschäftslogik und führt keine echten Aufrufe an das Netzwerk durch. Der Test ist unabhängig von externen Abhängigkeiten. – ant2009