Yoel Gluschnaider
Yoel Gluschnaider

Reputation: 1814

RxJava: How to unit test that an Observable is observed on and subscribed on the right scheduler?

I have the following scenario:

interface ItemsRepository {
    Observable<List<Item>> getItems();
}

class GetItems {
    private Scheduler ioScheduler;
    private Scheduler mainScheduler;
    private ItemsRepository itemsRepository;
    GetItems(Scheduler ioScheduler, 
             Scheduler mainScheduler, 
             ItemsRepository itemsRepository) {
        this.ioScheduler = ioScheduler;
        this.mainScheduler = mainScheduler;
        this.itemsRepository = itemsRepository;
    }

    Observable execute(Susbscriber subscriber) {
        return itemsRepository.getItems()
                              .subscribeOn(ioScheduler)
                              .observeOn(mainScheduler)
                              .subscribe(subscriber);
    }
}

Now I want to unit test that subscribeOn and observeOn are called using the correct Schedulers.

Upvotes: 2

Views: 1179

Answers (1)

Yoel Gluschnaider
Yoel Gluschnaider

Reputation: 1814

The way I did it was writing two unit tests as follows:

@RunWith(MockitoJUnitRunner.class)
class GetItemsTest {
    private GetItems getItems;
    private TestScheduler ioScheduler = Schedulers.test();
    private TestScheduler mainScheduler = Schedulers.test();
    private TestSubscriber<List<Item>> subscriber = new TestSubscriber();
    private List<Item> items;

    @Mock
    private ItemsRepository itemsRepository;

    @Before
    private void setUp() {
        getItems = new GetItems(ioScheduler, mainScheduler, itemsRepository);
        items = anyListOf(Item.class);
        given(itemsRepository.getItems()).willReturn(Observable.just(items));
        getItems.execute();
    }

    @Test
    public void should_subscribe_repository_on_the_io_scheduler throws Exception {
        subscriber.assertNoValues();

        mainScheduler.triggerActions();

        subscriber.assertNoValues();
    }

    @Test
    public void should_observe_repository_on_the_main_scheduler() throws Exception {
        subscriber.assertNoValues();

        ioScheduler.triggerActions();
        subscriber.assertNoValues();
        mainScheduler.triggerActions();

        subscriber.assertValue(trendingDestinations);
    }

}

I was wandering if there is a better solution. Just triggering the actions in order (io first and then main) will not cover the case where I accidentally use the ioScheduler twice. Also, the second test doesn't defend from using the mainScheduler twice as well. This solution, while defending against the right things, is not very readable and does not tell the reader how it is actually testing what it states in the name of the test method. I am using this solution for now, but would appreciate any suggestions.

Upvotes: 3

Related Questions