2016-09-20 65 views
3

我写一个单元测试和需要模拟可观察到的(来自改型)RxAndroid - java.lang.IllegalStateException:另一种策略已经注册

在所测试的组件中的代码如下:

getApiRequestObservable() 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribeOn(Schedulers.io()) 
       .subscribe(...) 

在单元测试(针对JVM所以AndroidSchedulers不可用),我需要让所有的同步,所以我的测试将是这样的:

@Test 
public void testSomething() { 
    doReturn(mockedResponse).when(presenter).getApiRequestObservable(); 
    presenter.callApi(); 
    verify(object,times(1)).someMethod(); 
} 

要做到这一点,我应该在设置()方法注册挂钩:

@Before 
    public void setUp() throws Exception { 

     // AndroidSchedulers.mainThread() is not available here so we fake it with this hook 
     RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() { 
      @Override 
      public Scheduler getMainThreadScheduler() { 
       return Schedulers.immediate(); 
      } 
     }); 

     // We want synchronous operations 
     RxJavaPlugins.getInstance().registerSchedulersHook(new RxJavaSchedulersHook(){ 
      @Override 
      public Scheduler getIOScheduler() { 
       return Schedulers.immediate(); 
      } 
     }); 
    } 

但是,这将引发上述异常,因为我显然没有获准注册两个挂钩。有没有办法解决这个问题?

回答

4

问题是您没有重置测试状态 - 您可以通过运行单个测试来验证。要解决您的具体问题,需要reset RX插件状态,像这样:

@Before 
public void setUp(){ 
    RxJavaPlugins.getInstance().reset(); 
    RxAndroidPlugins.getInstance().reset(); 
    //continue setup 
    ... 
} 

你甚至可以包复位到一个可重用@RuleAlexis Mas blog post描述:

public class RxJavaResetRule implements TestRule { 

    @Override 
    public Statement apply(Statement base, Description description) { 
     return new Statement() { 
      @Override 
      public void evaluate() throws Throwable { 
       //before: plugins reset, execution and schedulers hook defined 

       RxJavaPlugins.getInstance().reset(); 
       RxAndroidPlugins.getInstance().reset(); 
       // register custom schedulers 
       ... 
       base.evaluate(); 
      } 
     }; 
    } 
} 
相关问题