Espresso и Android сборщик контактов
Я пытаюсь добавить контакт с помощью сборщика контактов Android от Espresso, но это не работает.
Это команда для вызова средства выбора контактов:
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, RC_PICK_CONTACT);
Выбор контактов отображается, когда я запускаю тест Эспрессо. Хорошо, теперь я пытаюсь выбрать конкретную запись контакта по отображаемому имени (например, "Джейк"). К сожалению, я не знаю, как этого добиться. Я пробовал следующее:
onData(withItemContent("Jake")).inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))).perform(click());
Я также попробовал этот вариант:
onView(withText("Jake")).inRoot(withDecorView(not(is(getActivity().getWindow().getDecorView())))).perform(click());
Нет успеха с обоими подходами. Как уже упоминалось, сборщик контактов показан, но ничего не выбрано.
Любая идея?
1 ответ
Вы испытываете нормальное поведение, так как средство выбора контактов принадлежит к внешней деятельности, пользовательским интерфейсом которой нельзя манипулировать. Попытка утверждать что-либо приведет к тому, что тесты на какое-то время останавливаются и заканчиваются
android.support.test.espresso.NoActivityResumedException: Нет действий на этапе RESUMED. Вы забыли запустить мероприятие. (test.getActivity() или аналогичный)?
Тем не менее, поздоровайтесь с новорожденным Espresso-Intents, который здесь, чтобы спасти мою репутацию:
Используя соответствующий API (двоюродный брат Mockito.when), вы можете предоставить ответ для действий, которые запускаются с startActivityForResult
ОБНОВЛЕНИЕ Ниже мое текущее решение, которое отлично работает, но потребует некоторой приличной очистки кода:
@Test
public void testContactPickerResult(){
Intent resultData = new Intent();
resultData.setData(getContactUriByName("Joah"));
Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
intending(toPackage("com.google.android.contacts")).respondWith(result);
onView(withId(R.id.contactPickerLauncher))
.check(matches(isDisplayed()))
.perform(click());
onView(withId(R.id.pickedContact))
.check(matches(withText(getContactNumberByName("Joah"))));
}
В процессе запуска я бы обрабатывал входящее намерение с контактом Ури и делал с ним все необходимое.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
TextView result = (TextView) findViewById(R.id.pickedContact);
if (requestCode == 42 && resultCode == RESULT_OK){
Uri contactUri = data.getData();
String[] projection = {ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
cursor.moveToFirst();
int column = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = cursor.getString(column);
result.setText(number);
}
}
Кроме того, вспомогательные методы, которые будут изменены соответственно:
public Uri getContactUriByName(String contactName) {
Cursor cursor = mActivityRule.getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (name.equals(contactName)) {
return Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, id);
}
}
}
return null;
}