使用RxJava测试Android领域 - “从没有Looper的线程打开”异常

时间:2016-01-29 10:28:19

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

我有以下代码,基于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线程上运行,从我的理解是一个looper线程,因此这应该解决我的问题问题。我补充说:

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

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

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

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

1 个答案:

答案 0 :(得分:0)

SELECT pegawai.Nama, pegawai.Tempat_Lahir, pegawai.Tanggal_lahir, pegawai.NIP, pegawai.Tingkat_Ijasah, pegawai.Jurusan, pegawai.Golongan_CPNS, pegawai.TMT_CPNS, pegawai.Alamat, pensiun.TMT_Pensiun, pensiun.SKPensiun FROM pegawai JOIN pensiun ON pegawai.NIP = pensiun.NIP WHERE MONTH(pensiun.TMT_Pensiun) = MONTH(ADDDATE(CURDATE(), INTERVAL 1 MONTH)) 实际上并没有让你在一个工作的Looper线程上,只是在一个可以访问UI元素的线程上。我必须承认,我没有真正研究过为什么会有这种差异的细节。我们正在为Looper线程使用自定义规则(这也会清理我们的Realm实例)。你可以在这里看到它,也许可以用它作为灵感:

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