2017-06-29 17 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(); 
        } 
      )); 
} 

私のテスト:私はRxJavaPlugins.setIoSchedulerHandler(とそれを修正しようとした

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

@Beforeの他のメソッドを使用しても助けにはなりません。

+0

アンExceptionInInitializerErrorは、静的な初期化コードが例外をスローしていることを意味します。クラス内の静的初期化コードは、JVMがクラスをロードするときに実行されるため、Schedulersクラスには静的初期化コードのブロックが含まれていないように見えます。または、Schedulers.io()呼び出し内で参照されるクラス(静的初期化を含む)でもかまいません。スケジューラクラスが静的初期化中に必要な環境依存または構成依存関係を持つ場合、テストランタイムはこれらの依存関係を提供してはいけません。そこを見始める... –

答えて

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); 
} 
関連する問題