RxJava:如何对在正确的调度程序上观察和订阅Observable进行单元测试?

时间:2016-09-13 07:31:02

标签: java android unit-testing testing rx-java

我有以下情况:

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);
    }
}

现在我想要使用正确的subscribeOn来调用observeOnScheduler进行单元测试。

1 个答案:

答案 0 :(得分:2)

我这样做的方法是编写两个单元测试,如下所示:

@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);
    }

}

如果有更好的解决方案,我就会徘徊。只是按顺序触发动作(首先是io然后是main)将不会涵盖我偶然使用ioScheduler两次的情况。此外,第二次测试也没有防止使用mainScheduler两次。 这个解决方案在防御正确的事情的同时,并不是非常易读,也没有告诉读者它如何实际测试它在测试方法名称中的含义。 我现在正在使用此解决方案,但我将不胜感激任何建议。