In my architecture I use a class called a UseCase to compose an observable and subscribe to it. The UseCase takes in one or more Repositories in the constructor and has an "execute" method that is responsible for creating the observable and subscribing to it.
Here's a simple example;
public class MyUseCase {
IRepoA mRepoA;
IRepoB mRepoB;
Scheduler mScheduleOn;
Scheduler mObserveOn;
CompositeSubscription mCompositeSubscription;
public MyUseCase(IRepoA repoA, IRepoB repoB, Scheduler subscribeOn, Scheduler observeOn, CompositeSubscription compositeSubscription) {
mRepoA = repoA;
mRepoB = repoB;
mSubscribeOn = subscribeOn;
mObserveOn = observeOn;
mCompositeSubscription = compositeSubscription;
}
public Observable execute(Observable observable, Subscriber subscriber) {
if (observable == null) {
observable = mRepoA
.fetchLoginPreference()
.map(new Func1<LoginPreference, String>() {
@Override
public String call(LoginPreference loginPreference) {
return loginPreference.getActivationCode();
}
})
.flatMap(new Func1<String, Observable<List<RegistrationField>>>() {
@Override
public Observable<List<RegistrationField>> call(String s) {
return mRepoB.fetchRegistrationFields(s);
}
})
}
mCompositeSubscription.add(observable.subscribeOn(mSubscribeOn).observeOn(mObserveOn).subscribe(observable));
return observable;
}
}
It seems to me that there are a couple of things to test here and I'm wondering what the best way to go about it is.
1) I want to test that the observables are composed correctly. That is, I want to make sure that .map(), .flatMap(), and .cache() were called. The way I've done this before is to use mocks and verify that those methods were called on the mocks. So for instance, repoA.fetchLoginPreference() would return a mock observable and then I can verify that the mock has .map() called on it and so forth.
2) I want to test that the observable actually behaves correctly when I subscribe to it. To test this what I've done is to use real Observables instead of mocks. So when repoA.fetchLoginPreference() gets called I'd have it return Observable.just(mockLoginPreference). Then I use a TestSubscriber to subscribe to the resulting observable and verify that mocks are called correctly from within the Func1 callbacks.
Does this seem like a sane way of doing things? I end up being able to test both that the composition is correct and verify that when the observable is subscribed to it actually does what it's supposed to but I'm curious if there's a better way.