2016-01-29 15 views
5

Ho il seguente codice, in base al largo la documentazione fornita da Realm (https://realm.io/docs/java/latest/#rxjava)Test Android Realm con RxJava - "aperta da un filo senza un Looper" Eccezione

public Observable<Foo> getFooById(String id) { 

    realm = Realm.getInstance(realmConfiguration); 

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

Questo funziona in App come previsto tuttavia quando si tratta di testare le cose diventano un po 'più complicate. Ho la seguente prova (ridotta per mantenere le cose semplici):

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

Quando il test viene eseguito il seguente errore si verifica java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query.

Per contrastare questo ho letto sul Realm GitHub page che usano un'annotazione @UiThreadTest per forzare il test da eseguire sul thread UI, che dalla mia comprensione è un filo crochet, quindi questo dovrebbe risolvere il mio problema. Ho aggiunto:

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

e cambiato la mia prova per includere l'annotazione

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

Questo produce ancora la stessa eccezione. Qualcuno sa perché e una soluzione? Grazie.

risposta

0

Il @UiThreadTest non inserisce effettivamente un thread Looper funzionante, solo su un thread con accesso agli elementi dell'interfaccia utente. Devo confessare che non ho davvero esaminato i dettagli sul perché c'è questa differenza. Utilizziamo invece una regola personalizzata per i thread Looper (che pulisce anche le istanze di Realm). Potete vederlo qui e magari utilizzare che come ispirazione:

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

+0

Grazie per questo! Come passano questi test in quel caso? Soprattutto 'findFirstAsync_emittedOnSubscribe' in quanto questo è quasi identico a quello che sto facendo. https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTest/java/io/realm/RxJavaTests.java –

+0

Ho il sospetto che "AndroidSchedulers.mainThread" sia effettivamente non valido durante i test unitari. Puoi vedere nei nostri test che osserviamo solo sul thread predefinito. Solo un'ipotesi, però, non l'ho provato. –

+0

Grazie per il vostro aiuto, penso che per ora ho intenzione di espandere la nostra app di test di Realm per eseguire l'equivalente dei test che volevo eseguire. Sarebbe più facile e otteniamo ancora copertura. Il regno è fantastico ma il test unitario sembra abbastanza difficile, è qualcosa sulla tabella di marcia? –