2016-01-29 19 views
5

Mam następujący kod w oparciu off z dokumentacją dostarczoną przez Realm (https://realm.io/docs/java/latest/#rxjava)Testowanie Android Realm z RxJava - „otwarty z wątku bez Looper” wyjątek

public Observable<Foo> getFooById(String id) { 

    realm = Realm.getInstance(realmConfiguration); 

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

Działa to w aplikacji zgodnie z oczekiwaniami, jednak gdy do testowania rzeczy stają się nieco trudniejsze. Mam następujący test (uproszczoną keep it simple):

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

Kiedy test jest wykonywany następujący błąd występuje java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query.

Aby to czytałem na Realm GitHub page które używają one adnotację @UiThreadTest wymusić próbę uruchomić na wątków UI, która z mojego zrozumienia jest gwint looper licznik, więc to powinno rozwiązać mój problem. I dodaje:

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

i zmienił mój test zawierać adnotację

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

To wciąż daje ten sam wyjątek. Czy ktoś wie, dlaczego i rozwiązanie? Dzięki.

Odpowiedz

0

W rzeczywistości @UiThreadTest w rzeczywistości nie wprowadzi Cię do działającego wątku Looper, tylko na wątku z dostępem do elementów interfejsu użytkownika. Muszę przyznać, że tak naprawdę nie zajrzałem do szczegółów, dlaczego istnieje ta różnica. Zamiast tego używamy niestandardowej reguły dla wątków Looper (która również oczyszcza instancje Realm). Można go zobaczyć tutaj, a może użyć jej jako inspiracji:

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

+0

Dzięki za to! W jaki sposób testy te przechodzą w takim przypadku? Zwłaszcza 'findFirstAsync_emittedOnSubscribe', ponieważ jest prawie identyczny z tym, co robię. https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTest/java/io/realm/RxJavaTests.java –

+0

Mam podejrzenie, że 'AndroidSchedulers.mainThread' jest rzeczywiście nie ważne podczas testów jednostkowych. Możesz zobaczyć w naszych testach, które właśnie obserwujemy w domyślnym wątku. Chyba jednak nie przetestowałem tego. –

+0

Dzięki za pomoc, myślę, że teraz zamierzam rozszerzyć naszą aplikację testową Realm, aby uruchomić ekwiwalent testów, które chciałem uruchomić. Byłoby łatwiej i nadal zdobywamy zasięg. Realm's's great but Unit Testing wydaje się dość trudny, czy jest to coś na mapie drogowej? –