Testing onActivityResult()

android, instrumentation, java, junit, testing

Solution

Use intents framework to mock the activity result

intending(hasComponent(DummyActivity.class.getName())).respondWith(new ActivityResult(resultCode, dataIntent));
rule.getActivity().startActivityForResult(new Intent(context,DummyActivity.class));

verify on activity result logic

Problem

I have the following Activity: ``` package codeguru.startactivityforresult; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class StartActivityForResult extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.startButton = (Button) this.findViewById(R.id.start_button); this.startButton.setOnClickListener(onStart); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { int result = data.getIntExtra(StartActivityForResult.this.getString(R.string.result), -1); String msg = "requestCode=" + requestCode + ", resultCode=" + resultCode + ", result=" + result; Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } private View.OnClickListener onStart = new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(StartActivityForResult.this, ChildActivity.class); StartActivityForResult.this.startActivityForResult(intent, R.id.child_request); } }; private Button startButton = null; } ``` And the following JUnit test: ``` package codeguru.startactivityforresult; import android.app.Activity; import android.app.Instrumentation; import android.test.ActivityInstrumentationTestCase2; import android.test.UiThreadTest; import android.widget.Button; import junit.framework.Assert; public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> { public StartActivityForResultTest() { super(StartActivityForResult.class); } @Override public void setUp() throws Exception { super.setUp(); this.setActivityInitialTouchMode(false); this.activity = this.getActivity(); this.startButton = (Button) this.activity.findViewById(R.id.start_button); } @Override public void tearDown() throws Exception { this.activity.finish(); super.tearDown(); } @UiThreadTest public void testStartButtonOnClick() { Assert.assertTrue(this.startButton.performClick()); Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, null); Assert.assertNotNull(result); Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor(ChildActivity.class.getName(), result, true); Assert.assertNotNull(am); Activity childActivity = this.getInstrumentation().waitForMonitorWithTimeout(am, TIME_OUT); Assert.assertNotNull(childActivity); Assert.fail("How do I check that StartActivityForResult correctly handles the returned result?"); } private Activity activity = null; private Button startButton = null; private static final int TIME_OUT = 5 * 1000; // 5 seconds } ``` As you can see, I figured out how to mock up a result using `Instrumentation.ActivityResult` and `Instrumentation.ActivityMonitor`. How do I check that `StartActivityForResult.onActivityResult()` properly handles this result?

Original source