Тестирование щелчка на 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);

Это потому что просмотр списка еще не нарисован. Вам следует подождать, пока он будет нарисован, прежде чем пытаться получить доступ к его ячейкам.

Другие вопросы по тегам