-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testing the observers #223
Comments
I recommend you these links:
I hope they're helpful |
@urizev Thanks for the links, however, they don't explain how to test what the Observer do. In the example I mentioned above, how would you test that the onError() calls some methods on the view? |
You have some information ? Maybe see something like a TestRule implementation overriding a TestRule class with theses methods :
And use this class in presenter test : But nothing works ... (see : need help ;) |
First of all you need to understand that rule statement will be called after "before" method. I think you have to call trigger RxAndroidPlugins & RxJavaPlugins above in the static initializer of unit test class (static {...}) or static method annotated with BeforeClass. And don't reset trampoline scheduler, it is redundant. |
In fact, i've already worked with this type of Android architecture (in a work project), but we used RxJava 1.X and when we called a presenter we didn't have a "use case", we called a presenter method like that :
And in the unit test, we used the rule that I wrote before (with Rx Java 1 specifications) :
Here, when I try my solution or yours (called in @BeforeClass all RxAndroidPlugins.setInitMainThreadSchedulerHandler and cie), I always have the error : |
Let me share a solution which I usually use in such case. For example, we have a screen with list of articles. To fetch articles we have an use case public class GetArticlesUseCase extends UseCase<List<Article>> {
private final Repository repository;
@Inject
GetArticlesUseCase(Repository repository) {
this.repository = repository;
}
@Override
Observable<List<Article>> buildUseCaseObservable() {
return repository.getArticles();
}
} That's our presenter: public class ArticlesPresenter implements Presenter {
private final GetArticlesUseCase getArticlesUseCase;
@Inject
ArticlesPresenter(GetArticlesUseCase getArticlesUseCase) {
this.getArticlesUseCase = getArticlesUseCase;
}
...
public void loadArticles() {
getArticlesUseCase.execute(new ArticlesObserver());
}
...
private final class ArticlesObserver extends DefaultObserver<List<Article>> {
@Override
public void onComplete() {
view.hideLoading();
}
@Override
public void onError(Throwable error) {
view.hideLoading();
view.showError(error);
}
@Override
public void onNext(List<Article> articles) {
view.showArticles(articles);
}
}
} Then how we can test that, a particular methods will be called from observer callbacks: public class ArticlesPresenterTest {
@Mock private ArticlesView articlesView;
@Mock private GetArticlesUseCase getArticlesUseCase;
// this is our savior
@Captor private ArgumentCaptor<DefaultObserver<List<Article>>> articlesObserverCaptor;
@InjectMocks private ArticlesPresenter articlesPresenter;
...
@Test
public void loadArticles_showArticlesOnNoError() {
articlesPresenter.loadArticles();
verify(getArticlesUseCase).execute(articlesObserverCaptor);
// articlesList is a stubbed List<Article> which you want to use for verifying
articlesObserverCaptor.getValue().onNext(articlesList);
verify(articlesView).showArticles(eq(articlesList));
verify(articlesView).hideLoading();
}
@Test
public void loadArticles_showErrorMessageOnError() {
articlesPresenter.loadArticles();
verify(getArticlesUseCase).execute(articlesObserverCaptor);
// exception is any Throwable which you want to use for verifying
articlesObserverCaptor.getValue().onError(exception);
verify(articlesView).hideLoading();
verify(articlesView).showError(eq(exception));
}
...
} After that observer callback methods will be marked as covered by tests. You can find such approach in the popular android architecture blueprints repository. For example, TasksPresenter and TasksPresenterTest. |
Thanks @epetrenko. You're awesome! |
@epetrenko I had the same setup as you outlined but was struggling test. I just discovered "Captor", read up about it but wasnt sure how to use, your solution was perfect in helping with this. Thank you. |
Hi, I would like to test observers, based on the different results my UseCase may return. For example https://github.com/android10/Android-CleanArchitecture/blob/master/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java
In this case, onComplete(), onError() and onNext() are not tested. I'd like to be able to write a test named "testUserListObserverOnError" and make sure hideViewLoading(), showErrorMessage(), showViewRetry() are called.
I haven't managed to do that since the Observer class is a private inner class. I can not mock it. How would you go about testing this?
The text was updated successfully, but these errors were encountered: