Skip to content

3. Heroes Activity Test

David González edited this page Jul 31, 2016 · 10 revisions

What should I test?

This screen contains a list of Super Heroes. The main things to test are number of items in the list and visual consistency between what we expect and what we can see.

DaggerMock

A DaggerMockRule is an utility to let you create Dagger 2 modules dynamically. In this case we are using it to create a new MainModule in this testing scope. Instead of returning real objects, this new MainModule will return the mock for SuperHeroesRepository defined in this test.

@Mock
SuperHeroesRepository repository;

@Rule
public DaggerMockRule<MainComponent> daggerRule =
        new DaggerMockRule<>(MainComponent.class, new MainModule()).set(
                new DaggerMockRule.ComponentSetter<MainComponent>() {
                    @Override
                    public void setComponent(MainComponent component) {
                        SuperHeroesApplication app =
                                (SuperHeroesApplication) InstrumentationRegistry.getInstrumentation()
                                        .getTargetContext()
                                        .getApplicationContext();
                        app.setComponent(component);
                    }
                });

Test that the empty is displayed

Setup mocked SuperHeroesRepository to return a list of some Super Heroes.

private void givenThereAreNoSuperHeroes() {
    when(repository.getAll()).then(new Answer<List<SuperHero>>() {
        @Override
        public List<SuperHero> answer(InvocationOnMock invocation) throws Throwable {
            return Collections.emptyList();
        }
    });
}

There is already a test that verifies the empty list case

@Test public void showsEmptyCaseIfThereAreNoSuperHeroes() {
    givenThereAreNoSuperHeroes();

    startActivity();

    onView(withText(\\_(ツ)_/¯")).check(matches(isDisplayed()));
}

RecyclerView Interaction

As opposed to ListView, RecyclerView can't be tested as Adapters. There is a helper class called RecyclerViewInteraction that allows you to do assertions between Views and items in the list.

RecyclerViewInteraction.<ITEM_TYPE>onRecyclerView(withId(R.id.recycler_view))
.withItems(A_LIST_OF_ITEMS)
.check(new RecyclerViewInteraction.ItemViewAssertion<ITEM_TYPE>() {
    @Override
    public void check(ITEM_TYPE item, View view, NoMatchingViewException e) {
        matches(A_MATCHER).check(view, e);
    }
});

Things to test

  • The Super Hero names are shown in the list
  • The Avengers badge is only shown in the proper list items
  • Detail Activity is shown after clicking on a view element, etc...