Issue
How can i write test cases for the following code using espresso. I have following code which is executed when clicked on an icon. I know that i can check the launch of an intent using intended(toPackage(.... and possibly mocking the result of intent launched if it is launched via startActivityForResult but how to handle this case.
try {
intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" +"xxxxxx"); // 12 digit mobile no
if (intent.resolveActivity(context.getPackageManager()) != null) {
startActivity(intent)
}
}
catch (Exception e) {
Toast.makeText(getActivity(), "No phone number available", Toast.LENGTH_SHORT).show();
}
Solution
An answer is to use the 'intended' method after your test code to verify that the activity result meets your requirements. That looks like this:
@Test
public void typeNumber_ValidInput_InitiatesCall() {
// Types a phone number into the dialer edit text field and presses the call button.
onView(withId(R.id.edit_text_caller_number))
.perform(typeText(VALID_PHONE_NUMBER), closeSoftKeyboard());
onView(withId(R.id.button_call_number)).perform(click());
// Verify that an intent to the dialer was sent with the correct action, phone
// number and package. Think of Intents intended API as the equivalent to Mockito's verify.
intended(allOf(
hasAction(Intent.ACTION_CALL),
hasData(INTENT_DATA_PHONE_NUMBER),
toPackage(PACKAGE_ANDROID_DIALER)));
}
However, as part of a fully automated test, you'll need to stub out the response to the activity too so that it can run without actual blocking user input required. You'll need to set up intent stubbing before running tests:
@Before
public void stubAllExternalIntents() {
// By default Espresso Intents does not stub any Intents. Stubbing needs to be setup before
// every test run. In this case all external Intents will be blocked.
intending(not(isInternal())).respondWith(new ActivityResult(Activity.RESULT_OK, null));
}
Then you can write the corresponding part of the test like this:
@Test
public void pickContactButton_click_SelectsPhoneNumber() {
// Stub all Intents to ContactsActivity to return VALID_PHONE_NUMBER. Note that the Activity
// is never launched and result is stubbed.
intending(hasComponent(hasShortClassName(".ContactsActivity")))
.respondWith(new ActivityResult(Activity.RESULT_OK,
ContactsActivity.createResultData(VALID_PHONE_NUMBER)));
// Click the pick contact button.
onView(withId(R.id.button_pick_contact)).perform(click());
// Check that the number is displayed in the UI.
onView(withId(R.id.edit_text_caller_number))
.check(matches(withText(VALID_PHONE_NUMBER)));
}
If you need to verify with actual user input from another application (like the phone dialer), that is outside the scope of Espresso. Since I currently work with a vendor that helps with these kinds of cases, I hesitate to name names and tools, but lots of people do need to write tests that simulate the real end-to-end experience.
Mike Evans has a great write-up about testing intents here and there's always the android documentation here.
Answered By - Paul Bruce
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.