15

Is there any good way to test the result code and data in an Android Espresso test? I am using Espresso 2.0.

Suppose I have an Activity called BarActivity.class, which upon performing some action, calls setResult(int resultCode, Intent data) with the appropriate payload.

I'd like to write a test case to verify the resultCode and data. However, because setResult() is a final method, I can't override it.

Some options I thought about were:

  • Define a new method like setActivityResult() and just use that so it can be intercepted, etc...
  • Write a test-only TestActivity that will call startActivityForResult() on BarActivity and check the result in TestActivity.onActivityResult()

Trying to think what's lesser of the two evils, or if there's any other suggestions on how to test for this. Any suggestions? Thanks!

tomrozb
  • 25,773
  • 31
  • 101
  • 122
hiBrianLee
  • 1,847
  • 16
  • 19
  • Here is a partical solution for option 2: https://product.reverb.com/2016/03/12/testing-android-activity-results/ However, not complete, at least I didn't manage to make it work. – friedger May 16 '16 at 13:14

4 Answers4

21

If meanwhile you switched to the latest Espresso, version 3.0.1, you can simply use an ActivityTestRule and get the Activity result like this:

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

You can find a working example here.

Roberto Leinardi
  • 10,641
  • 6
  • 65
  • 69
5

If you are willing to upgrade to 2.1, then take a look at Espresso-Intents:

Using the intending API (cousin of Mockito.when), you can provide a response for activities that are launched with startActivityForResult

This basically means it is possible to build and return any result when a specific activity is launched (in your case the BarActivity class).

Check this example here: https://google.github.io/android-testing-support-library/docs/espresso/intents/index.html#intent-stubbing

And also my answer on a somewhat similar issue (but with the contact picker activity), in which I show how to build a result and send it back to the Activity which called startActivityForResult()

Community
  • 1
  • 1
appoll
  • 2,910
  • 28
  • 40
1

this works for me:


@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())))
    }

Assuming a validation like below on 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
                 }
            }
        }

I follow this guide as reference : https://developer.android.com/training/testing/espresso/intents and also i had to check this links at the end of the above link https://github.com/android/testing-samples/tree/master/ui/espresso/IntentsBasicSample and https://github.com/android/testing-samples/tree/master/ui/espresso/IntentsAdvancedSample

Oscar Ivan
  • 819
  • 1
  • 11
  • 21
0

If you're using ActivityScenario (or ActivityScenarioRule) as is the current recommendation in the Android Developers documentation (see the Test your app's activities page), the ActivityScenario class offers a getResult() method which you can assert on as follows:

@Test
fun result_code_is_set() {
    val activityScenario = ActivityScenario.launch(BarActivity::class.java)

    // TODO: execute some view actions which cause setResult() to be called

    // TODO: execute a view action which causes the activity to be finished

    val activityResult = activityScenario.result

    assertEquals(expectedResultCode, activityResult.resultCode)
    assertEquals(expectedResultData, activityResult.resultData)
}
Adil Hussain
  • 30,049
  • 21
  • 112
  • 147