Intro to Android

Lab: Testing

Fake Click

We can fake clicks on items using performClick(). Add the following to the ButtonFragmentTest:

@Test
public void oneShouldPostEvent() throws Exception
{
    Button key1 = (Button) buttonFragment.getView()
                            .findViewById( R.id.key1 );
    key1.performClick();
    verifyNumberButtonEvent( R.string.key1 );
}

The verification for each key will look pretty similar, so let's create a function:

private void verifyNumberButtonEvent( int stringId )
{
    BaseEvent event = buttonFragment.getEvent();
    assertTrue( event instanceof NumberButtonEvent );
    assertThat( ( (NumberButtonEvent) event ).getNumber(),
                equalTo( getString( strigId ) ) );
}

We'll be defining getEvent() in the next section.

Test class

We could use dependency injection or mocking frameworks to test that the events were triggered as expected, but instead we're going to just capture that an event happened.

Let's extend the class under test:

class TestButtonFragment extends ButtonFragment
{
    private BaseEvent event;

    @Override
    public void postToBus( BaseEvent event )
    {
        this.event = event;
    }

    BaseEvent getEvent()
    {
        return event;
    }
}

Notice that we're overriding the post to bus behavior and capturing it here. We use the event that was triggered for verification in the verifyNumberButtonEvent() function.

Notice that we're getting an error when we try to override the postToBus() method. That's because it doesn't exist yet!

Base Fragment

This isn't strictly a requirement, but it's useful to have a centralized Fragment.

Let's create a base fragment so that all fragments can post to the bus easily:

public class BaseFragment extends Fragment
{
    public void postToBus( BaseEvent event )
    {
        CalculatorApplication.postToBus( event );
    }

    @Override
    public void onResume()
    {
        super.onResume();
        registerWithBus();
    }

    @Override
    public void onPause()
    {
        super.onPause();
        unRegisterFromBus();
    }

    private void registerWithBus()
    {
        getBus().register( this );
    }

    private void unRegisterFromBus()
    {
        getBus().unregister( this );
    }

    protected Bus getBus()
    {
        return CalculatorApplication.getInstance().getBus();
    }
}

We also added the registration method here so that fragments can subscribe for events they are interested in.

Update

Now update ButtonFragment to extend BaseFragment. Also update ButtonFragmentTest to use a TestButtonFragment instead of a ButtonFragment.

Failing operator tests?

If you refactored your tests to loop through an array of numbers/operators to run your tests, you'll have to do some work here to treat operators and numbers separately.