UrbanPresenter implements MeaningPresenter, Observer<UrbanResult> { @Override public void onWordUpdated(String word) { Timber.d("Word updated : %s", word); if(subscription != null && !subscription.isUnsubscribed()) { subscription.unsubscribe(); } subscription = Observable.just(word) .filter(w -> w != null && !w.equals(UrbanPresenter.this.word)) .doOnNext(w -> { onMeaningsLoading(); updateWordOnPage(w); }) .flatMap(dictionary::resultsObservable) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this); } @Inject  UrbanPresenter(UrbanDictionary dictionary, UrbanMeaningAdapter adapter, MeaningsController controller); @Override void addView(View view); @Override void dropView(); @Override void onWordUpdated(String word); DictionaryException getDictionaryException(); void setDictionaryException(DictionaryException dictionaryException); @Override void onCompleted(); @Override void onError(Throwable e); @Override void onNext(UrbanResult urbanResult);  }
@Test public void testOnWordUpdated() throws Exception { String word = "Some word"; presenter.addView(meaningPage); presenter.onWordUpdated(word); verify(meaningPage).title(word); verify(meaningPage).meaningsLoading(); verify(dictionary).resultsObservable(word); reset(meaningPage); reset(dictionary); presenter.onWordUpdated(word); verify(meaningPage, never()).title(anyString()); verify(meaningPage, never()).meaningsLoading(); verify(dictionary, never()).resultsObservable(anyString()); }