Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Espresso testing: how test an activity's onNewIntent?

I'm wondering if there's a way to test an Activiy onNewIntent() method, I want to test launching an activity with the flag single top set and test some behaviour, how can this be achieved with espresso?

like image 957
Mina Wissa Avatar asked Jul 11 '17 13:07

Mina Wissa


People also ask

How do you test espresso intent?

Validate intents Using the intended() method, which is similar to Mockito. verify() , you can assert that a given intent has been seen. However, Espresso-Intents doesn't stub out responses to intents unless you explicitly configure it to do so. // User action that results in an external "phone" activity being launched.

How do you unit test an 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.


Video Answer


2 Answers

Calling it directly:

When you override onNewIntent() in your activity, you can make it public:

   @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

that way you can actually call it directly:

activityTestRule.getActivity().onNewIntent(new Intent())

This actually works, but it's not too good because you are calling the method from the testing app thread. If calling onNewIntent() will cause any changes on the UI you will get an exception because only the thread that created the view can change it. To fix this you can force running on the UI thread

activityTestRule.getActivity().runOnUiThread(() -> {
    activityTestRule.getActivity().onNewIntent(new Intent()));
});

This would allow you to test the onNewIntent() method of your activity.

A better way:

By the way you phrased your question, you also want to check some behaviour from the activity being defined as singleTop. Instead of calling the method directly, you can launch an intent that actually should trigger onNewIntent() in the activity under test:

Intent intent = new Intent(activityTestRule.getActivity().getApplicationContext(), ActivityUnderTest.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

InstrumentationRegistry.getTargetContext().startActivity(intent));

This should end up calling onNewIntent() of the activity under test as long as it's defined as singleTop, otherwise it will start a new activity instance.

like image 190
Lucas L. Avatar answered Oct 21 '22 16:10

Lucas L.


If you're using the ActivityTestRule, how about something like this?

Intents.init();
Intent intent = // Build your intent

rule.launchActivity(intent);

// Assertions    

Intents.release()

I'm not actually an Espresso user, but I'm assuming that will launch your activity and onNewIntent() will be called. Then make your assertions.

Note: this is using the Espresso Intents library, designed for this purpose.
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'

like image 22
Ben Kane Avatar answered Oct 21 '22 17:10

Ben Kane