2017-06-29 77 views
0

我正在學習編寫測試。 我寫了我的第一個測試,並從RxJava 2 + Retrofit中得到了錯誤。使用RxJava進行Android測試2

上線java.lang.ExceptionInInitializerError.subscribeOn(Schedulers.io())

代碼:

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中的其他方法,但它沒有幫助。

+0

創建一ExceptionInInitializerError意味着靜態初始化代碼拋出異常。當JVM加載類時,類中的靜態初始化代碼將運行,因此它看起來像Schedulers類包含一個失敗的靜態初始化代碼塊。或者它可能是一個在Schedulers.io()調用中引用的類(包含靜態初始化)。如果Schedulers類在其靜態初始化期間需要任何環境或配置依賴項,則測試運行時不能提供這些依賴項。開始看那裏... –

回答

1

這個固定我的問題:

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