Search code examples
androidlistviewtestingbroadcastreceiverandroid-context

Android testing : updating listview in a broadcast receiver onreceive


MyListActivity.java has a private BroadcastReceiver which updates a ListView as soon as it receives a broadcast. I want to test whether the listview gets updated after the broadcast is received. But I am having issues with MockContext.

This is what my test looks like.

public class MyListActivityTest extends ActivityInstrumentationTestCase2<MyListActivity>{
public void setUp()
{
    super.setUp();

    setActivityInitialTouchMode(false);

    mActivity = getActivity();
    myList = (ListView) mActivity.findViewById(R.id.myList);
        mContext = new MockContext();

}

public void testListUpdate()
{
    Intent in = new Intent("LIST_ITEM");
    in.putExtra("ITEM_VAL", "test2");

    try {
        Method method = MyListActivity.class.getMethod("getReceiver", null);
        BroadcastReceiver br = (BroadcastReceiver)method.invoke(mActivity, null);

        assertNotNull(br);

                    ArrayList<Item> list = new ArrayList<Item>();
                    list.add(new Item("test1"));
        ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(mActivity, android.R.layout.simple_list_item_1, list);     
            myList.setAdapter(adapter);

        br.onReceive(mContext, in);
        assertEquals(myList.getAdapter().getCount(), 1);
    }
            catch {..}
}

This gives me a CalledFromWrongThreadException, I guess because the adapter should be initialized and set in the MockContext instance mContext. But if I replace the parameter mActivity in ArrayAdapter constructor with mContext, it throws an UnsupportedOperationException in ArrayAdapter.init-> MockContext.getSystemService.

Please tell me how I can initialize the adapter in the same context as that of the receiver, so that the adapter gets updated after the onReceive and I can check if the adapter size increased by 1?

One option I have is to just monitor my datasource, whether it gets updated or not, but then my onReceive calls add to adapter, which is the one that throws the error!


Solution

  • To run something on the UI thread, you may want to call runTestOnUiThread:

    runTestOnUiThread(new Runnable() {
        @Override
        public void run() {
            // Here the actions you want to perform
        }
    });
    

    This will avoid CalledFromWrongThreadException