1

I'm learning to write tests. I wrote my first test and got error from RxJava 2 + Retrofit.

java.lang.ExceptionInInitializerError on line .subscribeOn(Schedulers.io())

Code:

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

My test:

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

I tried to fix it with RxJavaPlugins.setIoSchedulerHandler() and other method in @Before but it doesn't help.

1
  • An ExceptionInInitializerError means that static initialization code is throwing an exception. Static initialization code within a class runs when the JVM loads the class, so it looks like the Schedulers class contains a block of static initialization code that is failing. Or it could be a class (that contains static initialization) that is referenced within the Schedulers.io() call. If the Schedulers class has any environmental or configuration dependencies that are needed during its static initialization, the test runtime must not be providing those dependencies. Start looking there... Commented Jun 29, 2017 at 10:14

1 Answer 1

4

This fixed my issue:

@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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.