RxAndroid - java.lang.IllegalStateException:已经注册了另一个策略

时间:2016-09-20 20:30:13

标签: android rx-java rx-android

我正在编写一个单元测试,需要模拟一个Observable(来自改造)

测试组件中的代码如下:

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

为此,我应该在setUp()方法中注册钩子:

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

但这引发了上述异常,因为我显然不允许注册两个钩子。有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:6)

问题是您没有重置测试状态 - 您可以通过运行单个测试来验证。要解决您的特定问题,您需要reset rx插件状态如下:

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

您甚至可以按照Alexis Mas blog post的描述将重置包装到可重复使用的@Rule中:

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