I came across this limitation when trying to mock a class that refers to classes present in SDK >= 26 and executed the test in a device running SDK 24. I created a test app to better understand the problem.
open class RandomStuff{
@RequiresApi(Build.VERSION_CODES.O)
fun createDefaultNotificationChannel(): NotificationChannel {
return NotificationChannel("test", "test", NotificationManager.IMPORTANCE_DEFAULT)
}
fun testString(): String = "This is a test string"
}
Note that the RandomStuff class refers to the NotificationChannel class, only found in SDK >=26.
The test object provided via Dagger is the following:
@Module
class AppTestModule : AppModule() {
@Provides
override fun provideRandomStuff(): RandomStuff {
return mock(RandomStuff::class.java)
}
}
mock will fail with this exception: java.lang.IllegalArgumentException: Could not create type at provideRandomStuff(AppTestModule.kt) ultimately caused by a ClassNotFoundException thrown by ByteBuddy (a component used by Mockito). I was able to work around this issue by adding some checks to my provide method:
@Module
class AppTestModule : AppModule() {
@Provides
override fun provideRandomStuff(): RandomStuff? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return mock(RandomStuff::class.java)
} else {
return null
}
}
}
This temporary solution is very intrusive since now, the production code has to take into consideration that RandomStuff may be null. I call this a limitation since Mockito has always been promoted as a unit testing framework it does not seem that the Dagger + Espresso + Mockito is a fully supported combination. Is there a more creative solution for this issue?