Robolectric test ListView not updating after value changes in adapter
Asked Answered
M

2

9

I have created a layout with a ListView that updates values in it depending on which of the 2 given buttons are pressed. Pressing the button labelled Odds clears all values and adds odd numbers up until 20. Pressing evens does the same except for even numbers. This works fine when emulated or tried on a real device. Below is the activity code.

public class ListViewActivity extends Activity {

    private ListView mainListView;
    private ArrayAdapter<String> listAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.robolectric_test_main);

        mainListView = (ListView) findViewById(R.id.mainListView);

        ArrayList<String> numbersList = new ArrayList<String>();
        for (int i = 1; i < 21; i++) {
            numbersList.add(String.valueOf(i));
        }

        listAdapter = new ArrayAdapter<String>(this, R.layout.robolectric_listview_row, numbersList);

        mainListView.setAdapter(listAdapter);
    }

    public void onOddsClicked(View view) {
        listAdapter.clear();
        for (int i = 1; i < 21; i += 2) {
            listAdapter.add(String.valueOf(i));
        }
    }

    public void onEvensClicked(View view) {
        listAdapter.clear();
        for (int i = 2; i < 21; i += 2) {
            listAdapter.add(String.valueOf(i));
        }
    }
}

However when trying to test it with Robolectric the ListView is never updated even though the adapter has value modifications. Here is my test code.

@RunWith(RobolectricTestRunner.class)
public class ListViewActivityTest {

    private ListViewActivity listViewActivity;
    private Button oddsButton;
    private Button evensButton;
    private ListView numbersList;

    @Before
    public void setUp() throws Exception {
        listViewActivity = Robolectric.buildActivity(ListViewActivity.class).create().start().resume().visible().get();
        assignFields();
    }

    private void assignFields() {
        oddsButton = (Button) listViewActivity.findViewById(R.id.oddsButton);
        evensButton = (Button) listViewActivity.findViewById(R.id.evensButton);
        numbersList = (ListView) listViewActivity.findViewById(R.id.mainListView);
    }

    @Test
    public void odds() throws Exception {
        // check all numbers are odd
        Robolectric.clickOn(oddsButton);
        Robolectric.runUiThreadTasksIncludingDelayedTasks();
        for (int i = 0; i < numbersList.getChildCount(); i++) {
            TextView number = (TextView) numbersList.getChildAt(i);
            String numberString = number.getText().toString();
            int parsedInt = Integer.parseInt(numberString);
            assertTrue((parsedInt % 2) == 1);
        }
    }

    @Test
    public void evens() throws Exception {
        // check all numbers are even
        Robolectric.clickOn(evensButton);
        Robolectric.runUiThreadTasksIncludingDelayedTasks();
        for (int i = 0; i < numbersList.getChildCount(); i++) {
            TextView number = (TextView) numbersList.getChildAt(i);
            String numberString = number.getText().toString();
            int parsedInt = Integer.parseInt(numberString);
            assertTrue((parsedInt % 2) == 0);
        }
    }

}

Can you please let me know what I need to do in order to trigger the update on the ListView through Robolectric.

Miliaria answered 13/2, 2015 at 12:30 Comment(4)
In robolectric you must call ShadowListView.populateItems() to get adapter changes ShadowListView shadowListView = Robolectric.shadowOf(listView); shadowListView.populateItems();Appendage
Thank you @Appendage ! That fixed the issue I was having. I can't mark you as correct answer as you posted a comment.Miliaria
i used the wrong input field ^^Appendage
Done. Was away for a while, sorry for the delay.Miliaria
A
11

In robolectric you must call ShadowListView.populateItems() to get adapter changes

Robolectric 3.0

ShadowListView shadowListView = Shadows.shadowOf(mListView);
shadowListView.populateItems();

Robolectric 2.0

ShadowListView shadowListView = Robolectric.shadowOf(listView);
shadowListView.populateItems(); 
Appendage answered 13/2, 2015 at 19:31 Comment(0)
T
5

Just to update the answer to Robolectric 3.0

 ShadowListView shadowListView = Shadows.shadowOf(mListView);
    shadowListView.populateItems();
Topology answered 29/5, 2015 at 21:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.