In this document
Espresso-Intents is an extension to Espresso, which enables validation and stubbing of Intents sent out by the application under test. It’s like Mockito, but for Android Intents.
Packages
Open your app’s build.gradle file. This is usually not the top-level
build.gradle file but app/build.gradle. Add the following line inside
dependencies:
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
Espresso-Intents is only compatible with Espresso 2.1+ and the testing support library 0.3+ so make sure you update those lines as well:
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
Test rules
Use IntentsTestRule instead of ActivityTestRule when using Espresso-Intents.
IntentsTestRule makes it easy to use Espresso-Intents APIs in functional UI
tests. This class is an extension of ActivityTestRule, which initializes
Espresso-Intents before each test annotated with @Test and releases
Espresso-Intents after each test run. The activity will be terminated after each
test and this rule can be used in the same way as ActivityTestRule.
Validation
Espresso-Intents records all intents that attempt to launch activities from the
application under test. Using the intended API, closely related to
Mockito.verify(), you can assert that a given intent has been seen.
An example test that simply validates an outgoing intent:
@Test
public void validateIntentSentToPackage() {
// User action that results in an external "phone" activity being launched.
user.clickOnView(system.getView(R.id.callButton));
// Using a canned RecordedIntentMatcher to validate that an intent resolving
// to the "phone" activity has been sent.
intended(toPackage("com.android.phone"));
}
Stubbing
Using the intending API, closely related to Mockito.when(), you can provide a
response for activities that are launched with startActivityForResult(). This
is particularly useful for external activities since we cannot manipulate the
user interface of an external activity nor control the ActivityResult returned
to the activity under test.
The following code snippet contains an example test with intent stubbing:
@Test
public void activityResult_IsHandledProperly() {
// Build a result to return when a particular activity is launched.
Intent resultData = new Intent();
String phoneNumber = "123-345-6789";
resultData.putExtra("phone", phoneNumber);
ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);
// Set up result stubbing when an intent sent to "contacts" is seen.
intending(toPackage("com.android.contacts")).respondWith(result));
// User action that results in "contacts" activity being launched.
// Launching activity expects phoneNumber to be returned and displays it
// on the screen.
onView(withId(R.id.pickButton)).perform(click());
// Assert that data we set up above is shown.
onView(withId(R.id.phoneNumber).check(matches(withText(phoneNumber)));
}
Matchers
The intending() and intended() methods take a hamcrest Matcher<Intent>
object as an argument. Hamcrest is a library of matcher objects, also known as
constraints or predicates). You have the following options for
using them:
- Use an existing intent matcher: Easiest option, which should almost always be preferred.
- Implement your own intent matcher: Most flexible option. More details are available in the section entitled "Writing custom matchers" within the Hamcrest tutorial.
An example of intent validation with existing Intent matchers:
intended(allOf(
hasAction(equalTo(Intent.ACTION_VIEW)),
hasCategories(hasItem(equalTo(Intent.CATEGORY_BROWSABLE))),
hasData(hasHost(equalTo("www.google.com"))),
hasExtras(allOf(
hasEntry(equalTo("key1"), equalTo("value1")),
hasEntry(equalTo("key2"), equalTo("value2")))),
toPackage("com.android.browser")));