Jono
Jono

Reputation: 18118

Android instrumentation test failed due to mockito

Hi i am getting the following error


org.koin.error.BeanInstanceCreationException: Can't create definition for 'Single [name='NetworkControllerContract',class='com.network.contract.NetworkControllerContract']' due to error :

Mockito cannot mock this class: class com.network.NetworkController.

I have manually made those classes open..

open class NetworkController constructor(private val networkHelper: NetworkHelperContract) : NetworkControllerContract{.....}

open interface NetworkControllerContract {
}

//my test class

@RunWith(AndroidJUnit4::class)
class MyUnitTest: KoinTest {

   single<NetworkControllerContract> {
            Mockito.mock(NetworkController::class.java) //where it crashes
        }

   val networkController: NetworkControllerContract by inject()

}

Dependencies i use


   def mockito = "2.21.0"

//android instrumental test
    androidTestImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.ext:truth:1.1.0'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation('androidx.arch.core:core-testing:2.0.0') {
        exclude group: 'org.mockito:mockito-core'
    }
    androidTestUtil 'androidx.test:orchestrator:1.1.1'
    androidTestImplementation 'com.github.tmurakami:dexopener:2.0.0'

    androidTestImplementation 'com.jraska.livedata:testing-ktx:0.6.0'
    androidTestImplementation 'com.jraska.livedata:testing:0.6.0'

    androidTestImplementation "org.mockito:mockito-core:$mockito"
    androidTestImplementation("org.mockito:mockito-android:$mockito") {
        exclude group: 'org.mockito'
    }

    androidTestImplementation('org.koin:koin-test:1.0.2') {
        exclude group: 'org.mockito'
    }

 testImplementation 'junit:junit:4.12'
    testImplementation "org.mockito:mockito-core:$mockito"
    testImplementation "org.mockito:mockito-android:$mockito"
    testImplementation "org.mockito:mockito-inline:$mockito"
    testImplementation 'org.koin:koin-test:1.0.2'
    testImplementation 'androidx.test.ext:junit:1.1.0'
    testImplementation 'androidx.arch.core:core-testing:2.0.0'
    testImplementation 'com.jraska.livedata:testing-ktx:0.6.0'
    testImplementation 'com.jraska.livedata:testing:0.6.0'
    testImplementation 'androidx.test.ext:truth:1.1.0'

Upvotes: 0

Views: 1409

Answers (2)

Alexander
Alexander

Reputation: 551

It is my decision for mocking

@RunWith(AndroidJUnit4::class)
class DashboardFragmentTest : KoinTest {
    @Rule
    @JvmField
    val activityRule = ActivityTestRule(SingleFragmentActivity::class.java, true, true)
    @Rule
    @JvmField
    val executorRule = TaskExecutorWithIdlingResourceRule()
    @Rule
    @JvmField
    val countingAppExecutors = CountingAppExecutorsRule()

    private val testFragment = DashboardFragment()

    private lateinit var dashboardViewModel: DashboardViewModel
    private lateinit var router: Router

    private val devicesSuccess = MutableLiveData<List<Device>>()
    private val devicesFailure = MutableLiveData<String>()

    @Before
    fun setUp() {
        dashboardViewModel = Mockito.mock(DashboardViewModel::class.java)
        Mockito.when(dashboardViewModel.devicesSuccess).thenReturn(devicesSuccess)
        Mockito.when(dashboardViewModel.devicesFailure).thenReturn(devicesFailure)
        Mockito.when(dashboardViewModel.getDevices()).thenAnswer { _ -> Any() }

        router = Mockito.mock(Router::class.java)
        Mockito.when(router.loginActivity(activityRule.activity)).thenAnswer { _ -> Any() }

        StandAloneContext.loadKoinModules(hsApp + hsViewModel + api + listOf(module {
            single(override = true) { router }
            factory(override = true) { dashboardViewModel } bind ViewModel::class
        }))

        activityRule.activity.setFragment(testFragment)
        EspressoTestUtil.disableProgressBarAnimations(activityRule)
    }

    @After
    fun tearDown() {
        activityRule.finishActivity()
        StandAloneContext.closeKoin()
    }

    @Test
    fun devicesCall() {
        onView(withId(R.id.rv_devices)).check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed()))
        Mockito.verify(dashboardViewModel, Mockito.times(1)).getDevices()
    }
}

Upvotes: 0

Simon Harvan
Simon Harvan

Reputation: 701

Problem is in your setup:

testImplementation "org.mockito:mockito-android:$mockito"

This dependency uses Android internals, which aren't available when you run Unit tests.

Upvotes: 0

Related Questions