2016-07-21 7 views
16

HintergrundTesting RxBinding RxSearchView

public Observable<List<Foo>> search(SearchView searchView) { 

    return RxSearchView.queryTextChanges(searchView) 
      .filter(charSequence -> !TextUtils.isEmpty(charSequence)) 
      .throttleLast(100, TimeUnit.MILLISECONDS) 
      .debounce(200, TimeUnit.MILLISECONDS) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribeOn(AndroidSchedulers.mainThread()) 
      .flatMap(this::performSearch) //Search the DB 
      .onErrorResumeNext(this::doSomething); 
} 

Ich versuche, das obige Verfahren unter Verwendung des AndroidJUnit4 Läufer und Mocktio zu testen.

@Test 
public void testSearchCallsDataManager_WhenCalled() { 

    String input = "abc"; 

    when(mockSearchView.getQuery()).thenReturn(input); 

    searchRequestManager.search(mockSearchView).subscribe(testSubscriber); //Using standard TestSubscriber 

    testSubscriber.assertNoErrors(); 
    testSubscriber.assertNotCompleted(); 
    verify(mockDataManager).getFoos(input); 
} 

Das Problem

Ich habe versucht, eine mockSearchView und eine echte SearchView verwenden.

mockSearchView = mock(SearchView.class); 
searchView = new SearchView(InstrumentationRegistry.getContext(), null); 
searchView = new SearchView(InstrumentationRegistry.getTargetContext(), null); 

Die realen Objekte führen zu verschiedenen Ausnahmen, wenn der Test während ihrer Instanziierung ausgeführt wird. Das Scheinobjekt scheint während der Ausführung keine Wirkung zu haben.

aktualisieren

Aus Gründen der Klarheit: Im Idealfall wäre es toll, wenn ich die Suche verspotten konnte, wie ich testen wollen, was etwas passiert, nachdem emittiert wird, und dass die performSearch Verfahren mit den richtigen Eingängen aufgerufen wird.

+0

Wie instanziieren Sie InstrumentationRegistry? Normalerweise mache ich so etwas: @Rule public ActivityTestRule mBaseActivity = new ActivityTestRule <> (YourActivity.class, true, true); Und dann können Sie SearchView searchView = neue SearchView (mBaseActivity.getActivity()); – rxDroid

Antwort

1

Zum Testen von RxBindings habe ich einfach nur Espresso verwendet und debounce auf 0 gesetzt (Entprellzeit als öffentliche statische und in Espresso setUp() Methode habe ich es auf 0). Dann einfach

onView(withId(yourId)).perform(ViewActions.replaceText(to something)) 

und nur Ihre Mockito überprüfen oder was auch immer ähnlich mit throttleLast() Operator.

Prost

+0

Danke für die Antwort, das ist nützlich, wenn ich zu BDD gehe, aber der Test läuft in der JVM, um zu testen, dass die Ausgabe des SearchView eine Suche über den DataManager auslöst. Die Antwort könnte sein, dass der Test als Espresso-Test ausgeführt werden muss, aber ich hatte gehofft, dass dieser spezifische Test auf der JVM ausgeführt werden könnte, da ich den SearchView zu diesem Zeitpunkt eigentlich gar nicht interessiert. –

+0

so wird Mockito wahrscheinlich nicht gut genug sein, um searchView zu verhöhnen. Versuchen Sie es mit PowerMockito oder etwas Ähnlichem. Aber ich glaube, dass es zu viel Arbeit sein wird, um es zu umgehen, und SearchView ist UI, also sollte es in Instrumentation-Teil getestet werden. Und wenn Sie testen möchten, wenn etwas emitiert wird, testen Sie einfach Ihren Code performSearch und doSomething und im Instrumentation-Teil testen Sie einfach, dass es ausgelöst wird. So sollte es gemacht werden –