Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

testing that an activity called setResult

I'm writing tests for an activity (my test class extends ActivityInstrumentationTestCase2), I've got some basic tests written and working fine.

However my activity when it completes returns extra data to the calling activity via setResult(resultcode, Intent i) What I'd like to do using instrumentation get my activity to finish, then check what it passed in the setResult call.

Is there some framework provided way of doing this? i haven't been able to find anything yet, one approach would be to subclass the activity class and override setResult to have it remember & expose what was passed to setResult (turns out setResult is final, so you can't do this either), it seems like there should be a better way.

like image 840
superfell Avatar asked Nov 12 '10 01:11

superfell


People also ask

How do you test activity?

To test an activity, you use the ActivityTestRule class provided by the Android Testing Support Library. This rule provides functional testing of a single activity. The activity under test will be launched before each test annotated with @Test and before any method annotated with @Before.

How do you use Startactivity for results?

Android App Development for BeginnersStep 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml. In the above code, we have taken text view to show on Activity result data.

How do I get data from startActivityForResult?

First you use startActivityForResult() with parameters in the first Activity and if you want to send data from the second Activity to first Activity then pass the value using Intent with the setResult() method and get that data inside the onActivityResult() method in the first Activity .


3 Answers

As I answered in another questiom, you could also use Robolectric and shadow the Activity under test. Then, ShadowActivity provides you with methods to easily know if an Activity is finishing and for retrieving its result code.

As an example, one of my tests looks like this:

@Test
public void testPressingFinishButtonFinishesActivity() {
    mActivity.onCreate(null);
    ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity);

    Button finishButton = (Button) mActivity.findViewById(R.id.finish_button);
    finishButton.performClick();

    assertEquals(DummyActivity.RESULT_CUSTOM, shadowActivity.getResultCode());
    assertTrue(shadowActivity.isFinishing());
}

For Robolectric 3+ replace

ShadowActivity shadowActivity = Robolectric.shadowOf(mActivity);

with

ShadowActivity shadow = Shadows.shadowOf(activity);
like image 64
Edu Zamora Avatar answered Oct 17 '22 14:10

Edu Zamora


See my answer from another similar question:

You can use reflection and grab the values directly from the Activity.

protected Intent assertFinishCalledWithResult(int resultCode) {
  assertThat(isFinishCalled(), is(true));
  try {
    Field f = Activity.class.getDeclaredField("mResultCode");
    f.setAccessible(true);
    int actualResultCode = (Integer)f.get(getActivity());
    assertThat(actualResultCode, is(resultCode));
    f = Activity.class.getDeclaredField("mResultData");
    f.setAccessible(true);
    return (Intent)f.get(getActivity());
  } catch (NoSuchFieldException e) {
    throw new RuntimeException("Looks like the Android Activity class has changed it's   private fields for mResultCode or mResultData.  Time to update the reflection code.", e);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}
like image 26
Valdis R Avatar answered Oct 17 '22 15:10

Valdis R


Another approach would be to use modern mocking framework like jmockit - this way you can simulate behavior of android classes without emulator etc. You can see sample of it in my unit tests: https://github.com/ko5tik/jsonserializer ( previous versions worked against JSON bundled with android, and actual against GSON, but mocking logic is still there )

like image 43
Konstantin Pribluda Avatar answered Oct 17 '22 15:10

Konstantin Pribluda