使用RxJava 2进行Android测试

时间:2017-06-29 09:37:31

标签: java android unit-testing rx-java

我正在学习写测试。 我写了第一个测试,并从RxJava 2 + Retrofit中得到了错误。

.subscribeOn(Schedulers.io())

java.lang.ExceptionInInitializerError

代码:

public void search(String query) {
    getViewState().showProgress();
    disposable.add(dataManager
            .searchMovies(query)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    response -> {
                        getViewState().hideProgress();
                        if(response.isSuccessful()) {
                            getViewState().showSearchResults(response.body());
                        } else {
                            getViewState().showToast("Error " + response.code());
                        }
                    }, e -> {
                        getViewState().showToast(e.getMessage());
                        getViewState().hideProgress();
                    }
            ));
}

我的测试:

public class SearchPresenterTest {
    @Rule
    public TestComponentRule testComponentRule = new TestComponentRule();

    SearchPresenter searchPresenter;
    @Mock ISearchView$$State searchView$$State;
    @Mock DataManager dataManager;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);

        RxJavaPlugins.reset();
        RxJavaPlugins.setInitIoSchedulerHandler(schedulerCallable -> Schedulers.trampoline());

        RxAndroidPlugins.reset();
        RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline());

        RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline());
        RxAndroidPlugins.setMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline());

        searchPresenter = new SearchPresenter();
        searchPresenter.setViewState(searchView$$State);
    }

    @Test
    public void searchTest() {
        MovieList movieList = new MovieList();
        Response response = Response.success(new MovieList());
        Observable<Response<MovieList>> obs = Observable.just(response);

        when(dataManager.searchMovies(anyString())).thenReturn(obs);
        searchPresenter.search(searchRequest());

        verify(searchView$$State).showProgress();
        verify(searchView$$State).hideProgress();
        verify(searchView$$State).showSearchResults(movieList);
    }

    private String searchRequest() {
        return "pirates";
    }
}

我尝试用 RxJavaPlugins.setIoSchedulerHandler()和@Before中的其他方法修复它,但它没有帮助。

1 个答案:

答案 0 :(得分:4)

这解决了我的问题:

@BeforeClass
public static void setUpRxSchedulers() {
    Scheduler immediate = new Scheduler() {
        @Override
        public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
            // this prevents StackOverflowErrors when scheduling with a delay
            return super.scheduleDirect(run, 0, unit);
        }

        @Override
        public Worker createWorker() {
            return new ExecutorScheduler.ExecutorWorker(Runnable::run);
        }
    };

    RxJavaPlugins.setInitIoSchedulerHandler(scheduler -> immediate);
    RxJavaPlugins.setInitComputationSchedulerHandler(scheduler -> immediate);
    RxJavaPlugins.setInitNewThreadSchedulerHandler(scheduler -> immediate);
    RxJavaPlugins.setInitSingleSchedulerHandler(scheduler -> immediate);
    RxAndroidPlugins.setInitMainThreadSchedulerHandler(scheduler -> immediate);
}