Stubbing your Android Intents
Know your intent was sent without the Activity opening
Photo by marc thiele, used under a creative commons license. https://flic.kr/p/7aMoPV
In my previous post, I talked about how handy it is to use espresso intents to test which intents are sent in your Android application. I have since run into a new problem. In the application I’m working on we have a button that opens a link in the user’s browser. When this feature was added, we included a test to make sure our new button worked as expected.
Intents.init(); onView(withId(R.id.button)).perform(click()); Matcher expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(correct_url)); intended(expectedIntent); Intents.release();
This correctly tested that the browser was opened with the correct URL, but it made the rest of our test suite unhappy. It didn’t know what to do when an application other than ours was opened. Since we didn’t need to know anything other than that the browser intent was sent, we wondered if there was a way to keep it from opening while still testing what we needed to.
We discovered that
Intents also has a method,
intending(), that enables intent stubbing. When we stub an intent, we are able to intercept it so the intent is never sent to the system, and specify how it should respond. Through using this method, we were able to solve our issue with only one line of code.
intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null));
Notice that we also have a
.respondWith(). This lets us specify the
ActivityResult for the stubbed intent, and it needs to be included if the intent is going to be intercepted correctly. We don’t use any response for our example, so we just used empty data.
intending() method doesn’t assert that the intent was sent, but when we combine it with the
intended() check we had before, we have the exact behavior we are looking for in our test!
Intents.init(); Matcher expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(correct_url)); intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null)); onView(withId(R.id.button)).perform(click()); intended(expectedIntent); Intents.release();