4

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?

0 Answers0