16

Background

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

I am trying to test the above method using the AndroidJUnit4 runner and Mocktio.

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

The Problem

I have tried using a mockSearchView and a real SearchView.

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

The real objects result in different exceptions when the test runs, during their instantiation. The mock object seems to have no effect during execution.

Update

For clarity: Ideally it would be great if I could mock the SearchView as I want to test what happens AFTER something is emitted and that the performSearch method is called with the correct inputs.

Graham Smith
  • 25,627
  • 10
  • 46
  • 69
  • How do you instantiate InstrumentationRegistry? I usually do something like this: @Rule public ActivityTestRule mBaseActivity = new ActivityTestRule<>(YourActivity.class, true, true); And then you can do SearchView searchView = new SearchView(mBaseActivity.getActivity()); – Camino2007 Jul 22 '16 at 13:33

1 Answers1

1

For testing RxBindings I just simply used Espresso and set debounce to 0 ( debounce time as public static, and in espresso setUp() method I set it up to 0). Then just

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

and just verify your Mockito or whatever similar with throttleLast() operator.

Cheers

mmBs
  • 8,421
  • 6
  • 38
  • 46
wojciech_maciejewski
  • 1,277
  • 1
  • 12
  • 28
  • Thanks for the answer, this useful when I move to BDD but the test runs in the JVM to test that the output of the SearchView triggers a search via the DataManager. The answer might be the test needs to run as an Espresso test but I was hoping this specific test could run on the JVM, as I don't actually care about the SearchView at this point. – Graham Smith Aug 04 '16 at 09:45
  • so Mockito will be probably not good enought to mock searchView. Try using PowerMockito or something similar. But I belive that it will be to much work to go around it, and SearchView is UI so it should be tested in Instrumentation part. And if you want to test when something is emited so just test your code performSearch and doSomething and in Instrumentation part just test that it is triggerd. Thats the way it should be done – wojciech_maciejewski Aug 04 '16 at 10:12