Intro To Android (Workbook 2)

Testing the adapter

When testing the adapter for our list view, we want to verify that:

  • View adapter members that are managed by the list view return proper values: getCount(), getItem(), getItemId()
  • All views returned by getView() are inflated and configured properly
  • Views are recycled as expected

We verify on each item in our source data, so most tests include a for loop:

public class ImageAdapterTest
{
    private static final String URL      = "http://one";
    private static final String URL_PART = "/two";

    private ImageAdapter             listAdapter;
    private ArrayList<InventoryItem> items;

    @Before
    public void setUp() throws Exception
    {
        populateListOfUrls();
        listAdapter = new ImageAdapter( startActivity(), items );
    }

    private void populateListOfUrls()
    {
        items = new ArrayList<InventoryItem>();
        items.add( new InventoryItem( "Tomato", 2, R.drawable.tomato, URL ) );
        items.add( new InventoryItem( "Tomato",
                                      2,
                                      R.drawable.tomato,
                                      URL_PART ) );
        items.add( new InventoryItem( "Apple",
                                      6,
                                      R.drawable.app_icon,
                                      URL ) );
    }

    @Test
    public void shouldNotBeNull() throws Exception
    {
        assertNotNull( listAdapter );
    }

    @Test
    public void getCount_shouldReturnProperCount() throws Exception
    {
        assertEquals( listAdapter.getCount(), items.size() );
    }

    @Test
    public void getItem_shouldReturnProperItem() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            assertEquals( listAdapter.getItem( index ),
                          items.get( index ) );
        }
    }

    @Test
    public void getItemId_shouldReturnProperItemId() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            assertEquals( listAdapter.getItemId( index ), index );
        }
    }

    @Test
    public void getView_shouldReturnView() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            assertNotNull( getViewAtIndex( index ) );
        }
    }

    @Test
    public void viewReturnedByGetViewShouldHaveName() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            View view = getViewAtIndex( index );
            assertViewIsVisible( view.findViewById( R.id.inventory_item_image ) );
        }
    }

    @Test
    public void viewReturnedByGetViewShouldHaveTextAmount() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            View view = getViewAtIndex( index );
            assertViewIsVisible( view.findViewById( R.id.inventory_item_amount ) );
        }
    }

    @Test
    public void viewReturnedByGetViewShouldHaveImage() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            View view = getViewAtIndex( index );
            assertViewIsVisible( view.findViewById( R.id.inventory_item_image ) );
        }
    }

    private View getViewAtIndex( int index )
    {
        return listAdapter.getView( index, getRecycleView(), null );
    }

    @Test
    public void shouldRecycleViews() throws Exception
    {
        for ( int index = 0; index < items.size(); index++ )
        {
            View recycleView = getRecycleView();
            View listItemView = listAdapter.getView( index,
                                                     recycleView,
                                                     null );
            assertSame( recycleView, listItemView );
        }
    }

    private View getRecycleView()
    {
        View recycleView = View.inflate( startActivity(),
                                         R.layout.inventory_item,
                                         null );

        ImageAdapter.ViewHolder viewHolder = createViewHolder( recycleView );
        recycleView.setTag( viewHolder );

        return recycleView;
    }
}

Most of these tests are straight forward, but we should examine test shouldRecycleViews() a bit further.

Here's the logic behind it:

  1. We create a view using the ViewHolder that looks like it's recyclable (has a tag set by setTag).
  2. We call the getView() function with this recycleView (aka. convertView).
  3. We ensure that the view we passed in was returned by getView().