Mocking in In-App Purchase UI Tests — Mockito, Dagger2 and Espresso

Augustine Kwong
Aug 31, 2018 · 4 min read

Testing In-App Purchase (IAP) flow is especially difficult — completing the flow produces side effects that are hard to reverse, e.g. upgrading a user or making a purchase, so it makes sense to mock these calls even in a UI test. In this article we will create Espresso UI Instrumented tests for Android that will proceed through the IAP, mocking the responses from Google Billing and our own user database.

The stack

The process

Create directory your/folder/location/src/androidTest. It should be on the same level as src/main.

Within this directory, mirror your src/main/ directory structure.

  1. Create a test DaggerComponent in /androidTest/com/domain/.../dagger, one that will supply our mocked dependencies.
  2. Create a test DaggerApplication, one that will receive our mocked modules.
  3. Create a test runner that uses our test application.
  4. Write tests! Run with the test runner.

Step one — Dagger Component

A quick overview of Dagger2. In order to provide dependencies:

  1. Specify module classes that provide objects of a certain class type. The class is annotated with @Module and methods are annotated with @Provides. The names don’t matter and are just convention. The return type of the method is what’s used in the graph. For tests, it is useful to annotate all @Provides with @Singleton
class MockAppModule {
fun provideUserManager = UserManager()
fun provideApi = mock(

2. Specify a Component; An adapter between your modules and your injected fields. @Components can be built and injected into different contexts to provide injected fields.

@Component(modules = arrayOf(MockAppModule::class))
interface MockComponent : AndroidInjector<TestApplication> {
fun inject(tests: ApplicationUITests)}

There are 2 new additions we will ignore for the time being, TestApplication and the inject method.

Step Two — Create a test application

Our tests have a different dependency graph than our production application. Create a test application that uses our test dependency graph.

class TestApplication : DaggerApplication() {

lateinit var component: TestComponent

override fun applicationInjector(): AndroidInjector<out DaggerApplication> = DaggerTestComponent
.also { component = it }

For Dagger to recognize that the annotations in TestComponent needs to be generated into a TestComponent, add to your build.gradle

kaptAndroidTest "$daggerVersion"
kaptAndroidTest "$daggerVersion"

Step Three — Specify an instrumented test runner

class TestApplicationRunner: AndroidJUnitRunner() {    override fun newApplication(cl: ClassLoader?, className: String?, context: Context?) = Instrumentation.newApplication(, context)


Set this as the Instrumented Test Runner in build.gradle of your app. Make sure you have:

android {
defaultConfig {
testInstrumentationRunner ""

Step Four — The test class

We’re mostly done. Only the classes in our modules that return mocks will be mocked. Within our test class, retrieve the TestAppplication’s component. Having used @Singleton for the dependencies will allow us to retrieve the same instances to mock certain calls.

In our test class, annotate the mocked classes and inject the test application’s singletons. We stub methods accordingly.

class ApplicationUITests {

internal var mockitoRule = MockitoJUnit.rule()

var activityTestRule = ActivityTestRule<PaywallActivity> .(, true, true)
internal lateinit var userManager: UserManager

val user = mock( {
/* return a real user or mock the properties here */
fun setupMocks() {
fun enterActivity_showsInfo() {
onView(withText("Hello World")).check(matches(isDisplayed()))


Here are some considerations

  • If you are also using Kotlin, you can only mock interfaces. This should be fine since all APIs should have an interface layer regardless
  • If you are having issues with asynchronous code that uses a loosely defined callback flow, consider using Espresso Idling Resources. The official documentation code says to embed idling resource calls in production code. There is no need for that, just use them inside your mocked calls.
  • Use the right tool for the job; this is a very specific use case so thoroughly consider whether methods need to be mocked in a UI test.

In general, use UI tests to ensure that core flows maintain their functionality. They are an integration and regression test. Adding stub methods when testing this flow is a consideration that shouldn’t be taken lightly.

About the author

Augustine Kwong is a Combined Major in Computer Science and Statistics at the University of British Columbia. He worked on the Core Mobile team, working predominantly on the Android app but branched out to work on backend in Scala.

Hootsuite Engineering

Hootsuite's Engineering Blog

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store