Skip to content

Instantly share code, notes, and snippets.

@jaredrummler
Created April 13, 2018 06:31
Show Gist options
  • Select an option

  • Save jaredrummler/3e3e27ec8c430e20a23f72115bb19cd6 to your computer and use it in GitHub Desktop.

Select an option

Save jaredrummler/3e3e27ec8c430e20a23f72115bb19cd6 to your computer and use it in GitHub Desktop.
Mock lazy injection using reflection

Method to set all @Inject fields in a class to mocks:

fun mockInjectables(obj: Any) {
    obj::class.java.declaredFields.forEach { field ->
        field.getAnnotation(Inject::class.java)?.apply {
            if (field.type.isAssignableFrom(dagger.Lazy::class.java)) {
                if (!field.isAccessible) field.isAccessible = true

                val type = field.genericType as ParameterizedType
                val mockClass = type.actualTypeArguments[0] as Class<*>

                val mockLazy = Mockito.mock(field.type) as dagger.Lazy<*>
                val mock = Mockito.mock(mockClass)

                field.set(obj, mockLazy)
                whenever(mockLazy.get()).thenReturn(mock)
            }
        }
    }
}

Example class:

class Foo {

  @Inject lateinit var bar: dagger.Lazy<Bar>
  @Inject lateinit var baz: dagger.Lazy<Baz>
  @Inject lateinit var qux: dagger.Lazy<Qux>
  
  // ... //
  
}
class FooTest {

  @Test
  fun some_test() {
    val foo = Foo()
    mockInjectables(foo)
    foo.bar.get() // <--- this is a mock. No more boilerplate.
  }

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment