Тестирование щелчка на Android ListView с ActivityUnitTestCase
Я реализовал ListView
это начинается новый Activity
при нажатии на элемент списка. Когда я проверяю это вручную, это работает отлично. Но когда я пытаюсь сделать автоматический тест с ActivityUnitTestCase
Я получаю NullPointerException
как будто ListView
был пуст.
MainActivity (частично):
public class MainActivity extends ListActivity {
@Override
protected void onResume() {
super.onResume();
String[] items = new String[] {"item 1", "item 2"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
setListAdapter(adapter);
getListView().setOnItemClickListener(new OnItemClickListener () {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView clickedItem = (TextView) view;
CharSequence clickedItemText = clickedItem.getText(); // throws a NullPointerException when running testWithPerformItemClick()!
Intent intent = new Intent(MainActivity.this, ItemDisplayActivity.class);
intent.putExtra("parameter", clickedItemText);
startActivity(intent);
}
});
}
}
Тестовый код, который не проходит:
public class MainActivityTest extends ActivityUnitTestCase<MainActivity> {
ListView listView;
View child0;
public MainActivityTest() {
super(MainActivity.class);
}
private void setUpTest() {
MainActivity activity = startActivity(new Intent(), null, null);
getInstrumentation().callActivityOnStart(activity);
getInstrumentation().callActivityOnResume(activity);
listView = (ListView) activity.findViewById(android.R.id.list);
child0 = listView.getChildAt(0); // returns null!
}
public void testWithPerformClick() {
setUpTest();
child0.performClick(); // throws a NullPointerException!
Intent startedIntent = getStartedActivityIntent();
assertEquals("item 1", startedIntent.getStringExtra("parameter"));
}
public void testWithPerformItemClick() {
setUpTest();
long itemId = listView.getAdapter().getItemId(0);
listView.performItemClick(child0, 0, itemId); // throws a NullPointerException!
Intent startedIntent = getStartedActivityIntent();
assertEquals("item 1", startedIntent.getStringExtra("parameter"));
}
Оба метода испытаний терпят неудачу, потому что listView.getChildAt(0)
возвращается null
, Почему ListView
пусто? Как я могу заставить его обновить себя с нужными детьми?
2 ответа
Согласно документации, если вы предпочитаете функциональный тест, вы должны использовать ActivityInstrumentationTestCase2. Для выполнения клика это работает лучше. Ответ @fewe правильный, вам нужно дождаться составления списка, чтобы дождаться загрузки фрагмента, вы можете использовать getInstrumentation(). WaitForIdleSync();
Попробуйте что-то вроде этого.
public class ActivityTests extends
ActivityInstrumentationTestCase2<Activity>
final ListView list = (ListView) mActivity.findViewById(R.id.listId);
assertNotNull("The list was not loaded", list);
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
list.performItemClick(list.getAdapter().getView(position, null, null),
position, list.getAdapter().getItemId(position));
}
});
getInstrumentation().waitForIdleSync();
Тогда вы не можете проверить, например, был ли загружен фрагмент.
mFragment frag = mActivity.getFragment();
assertNotNull("Fragment was not loaded", frag);
Это потому что просмотр списка еще не нарисован. Вам следует подождать, пока он будет нарисован, прежде чем пытаться получить доступ к его ячейкам.