Как я могу протестировать setResult() в тесте Android Espresso?

Есть ли хороший способ проверить код результата и данные в тесте Android Espresso? Я использую Эспрессо 2.0.

Предположим, у меня есть Activity с именем BarActivity.class, который при выполнении некоторого действия вызывает setResult(int resultCode, Intent data) с соответствующей полезной нагрузкой.

Я хотел бы написать тестовый пример для проверки resultCode и data. Однако, поскольку setResult() является методом final, я не могу его переопределить.

Некоторые варианты, о которых я думал, были:

  • Определите новый метод, например setActivityResult(), и просто используйте его, чтобы его можно было перехватить и т. д.
  • Напишите тестовую TestActivity, которая будет вызывать startActivityForResult() в BarActivity и проверять результат в TestActivity.onActivityResult()

Попытка подумать, что меньшее из двух зол, или есть ли какие-либо другие предложения о том, как это проверить. Какие-либо предложения? Спасибо!


person hiBrianLee    schedule 06.05.2015    source источник
comment
Вот частичное решение для варианта 2: product.reverb. com/2016/03/12/testing-android-activity-results Однако не полный, по крайней мере, мне не удалось заставить его работать.   -  person friedger    schedule 16.05.2016


Ответы (3)


Если вы хотите перейти на 2.1, посмотрите Эспрессо-намерения:

Используя предполагаемый API (двоюродный брат Mockito.when), вы можете предоставить ответ для действий, которые запускаются с помощью startActivityForResult.

В основном это означает, что можно создавать и возвращать любой результат при запуске определенного действия (в вашем случае это класс BarActivity).

Проверьте этот пример здесь: https://google.github.io/android-testing-support-library/docs/espresso/intents/index.html#intent-stubbing

А также мой ответ по несколько похожей проблеме (но с активностью средства выбора контактов), в котором я показываю, как создать результат и отправить его обратно в действие, которое вызвало startActivityForResult()

person appoll    schedule 07.05.2015
comment
Я не понимаю, как протестировать метод setResult с помощью Espresso-Intents. Не могли бы вы уточнить? - person friedger; 16.05.2016

Если тем временем вы переключились на последнюю версию Espresso 3.0.1, вы можете просто использовать ActivityTestRule и получить результат Activity следующим образом:

assertThat(rule.getActivityResult(), hasResultCode(Activity.RESULT_OK));
assertThat(rule.getActivityResult(), hasResultData(IntentMatchers.hasExtraWithKey(PickActivity.EXTRA_PICKED_NUMBER)));

Вы можете найти рабочий пример здесь.

person Roberto Leinardi    schedule 15.09.2017
comment
Это определенно самый чистый способ, если вы можете перейти на 3.0.1. - person skeeve; 03.11.2017
comment
Если hasResultCode и hasResultData не могут быть разрешены. Добавьте androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.1' в build.gradle - person Paglian; 19.02.2018
comment
Вы спасли мой день. Спасибо! - person Yuri Popiv; 21.04.2021

это работает для меня:


@Test
    fun testActivityForResult(){

        // Build the result to return when the activity is launched.
        val resultData = Intent()
        resultData.putExtra(KEY_VALUE_TO_RETURN, true)

        // Set up result stubbing when an intent sent to <ActivityB> is seen.
        intending(hasComponent("com.xxx.xxxty.ActivityB")) //Path of <ActivityB>
            .respondWith(
                Instrumentation.ActivityResult(
                    RESULT_OK,
                    resultData
                )
            )

        // User action that results in "ActivityB" activity being launched.
        onView(withId(R.id.view_id))
            .perform(click())

      // Assert that the data we set up above is shown.
     onView(withId(R.id.another_view_id)).check(matches(matches(isDisplayed())))
    }

Предполагая проверку, как показано ниже, для onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)


if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {

    data?.getBooleanExtra(KEY_VALUE_TO_RETURN, false)?.let {showView ->
                if (showView) {
                 another_view_id.visibility = View.VISIBLE
                }else{
                 another_view_id.visibility = View.GONE
                 }
            }
        }

Я следую этому руководству в качестве справки: https://developer.android.com/training/testing/espresso/intents, а также я должен был проверить эти ссылки в конце приведенной выше ссылки https://github.com/android/testing-samples/tree/master/ui/espresso/IntentsBasicSample и https://github.com/android/testing-samples/tree/master/ui/espresso/IntentsAdvancedSample

person Oscar Ivan    schedule 13.08.2020