【问题标题】:Testing Android Realm with RxJava - "opened from a thread without a Looper" Exception使用 RxJava 测试 Android 领域 - “从没有 Looper 的线程打开”异常
【发布时间】:2016-05-07 01:12:52
【问题描述】:

我有以下代码,基于 Realm (https://realm.io/docs/java/latest/#rxjava) 提供的文档

public Observable<Foo> getFooById(String id) {

    realm = Realm.getInstance(realmConfiguration);

    return realm.where(Foo.class)
            .equalTo("id", id)
            .findFirstAsync()
            .asObservable()
            .filter(this::filterResult);
}

这在应用程序中按预期工作,但是在测试方面变得有点棘手。我有以下测试(精简以保持简单):

@Test
public void testRealmExample() {

    RealmConfiguration config = new RealmConfiguration.Builder(context)
            .name("test.realm")
            .inMemory()
            .build();

    DataManager dataManager = new DataManager(config);

    TestSubscriber<Foo> testSubscriber = new TestSubscriber<>();
    dataManager.getFoo("").observeOn(AndroidSchedulers.mainThread()).subscribe(testSubscriber);
    testSubscriber.assertNoErrors();
}

执行测试时出现以下错误java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query

为了反驳这一点,我在Realm GitHub page 上读到他们使用注释@UiThreadTest 来强制测试在UI 线程上运行,据我了解,这是一个活套线程,因此这应该可以解决我的问题。我补充说:

@Rule
public final UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

并更改了我的测试以包含注释

@Test
@UiThreadTest
public void testRealmExample() { ...}

这仍然会产生相同的异常。有谁知道为什么和解决方案?谢谢。

【问题讨论】:

    标签: android unit-testing junit realm rx-java


    【解决方案1】:

    @UiThreadTest 实际上并没有把你放在一个工作的 Looper 线程上,只是放在一个可以访问 UI 元素的线程上。我必须承认,我还没有真正研究过为什么会有这种差异的细节。我们正在为 Looper 线程使用自定义规则(这也清理了我们的 Realm 实例)。你可以在这里看到它,也许可以以此为灵感:

    https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTest/java/io/realm/rule/RunInLooperThread.java

    【讨论】:

    • 谢谢!在这种情况下,这些测试如何通过?特别是findFirstAsync_emittedOnSubscribe ,因为这与我正在做的几乎相同。 github.com/realm/realm-java/blob/master/realm/realm-library/src/…
    • 我怀疑AndroidSchedulers.mainThread 在单元测试期间实际上是无效的。您可以在我们的测试中看到我们只是在默认线程上观察到的。只是一个猜测,我还没有测试过。
    • 感谢您的帮助,我想现在我将扩展我们的 Realm 测试平台应用程序来运行我想要运行的等效测试。这会更容易,我们仍然可以获得覆盖。 Realm 很棒,但单元测试似乎相当困难,这是路线图上的内容吗?
    • 是的,现在我们正在考虑添加对 Robolectric 的支持,并希望能够支持标准的 JUnit4。
    • 只有一件事:在测试中替换你的调度器。请参阅 Alexis MasFederico Paolinelli 的帖子了解如何执行此操作。
    猜你喜欢
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多