androidkotlinmockingmockitomockk

Mocking Static Methods - Kotlin


I've been using Mockito, Mockk and PowerMock to mock static methods, to not avail. I'm not sure if my understanding is correct, but I was expecting that, when I mock a (static or instance) method, the actual method implementation is bypassed and the provided value returned.

This seems to work great with instance methods, but for some reason I can't get it to work with static methods. It seems it actually goes into the mocked method's implementation (which forces me to go into the rabbithole of mocking the entire call chain).

I want to mock an isOnline(context: Context) method, which returns boolean by calling a series of Android calls to check for connectivity. I want to stub this method to return true or false depending on the test scenario, but upon passing it a mocked context, I get an error about casting null to ConneectivityManager (included snippet of implementation below).

Example (using Mockk): The mocking:

context = Mockito.mock(Context::class.java)
mockkStatic(NetworkManager::class)
every { NetworkManager.isOnline(context) } answers { true}

The test:

assertThat(NetworkManager.isOnline(context)).isTrue()

NetworkManager snippet:

fun isOnline(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager` <-- here's where the test fails, says that cannot cast null to 

Same happens when using Mockito:

mockStatic(NetworkManager::class.java)
    .use { mocked ->
        mocked.`when`<Boolean> { NetworkManager.isOnline(context) }.thenReturn(true)
        assertThat(NetworkManager.isOnline(context)).isTrue()
}

PowerMock/EasyMock:

context = mock(Context::class.java);
createMock(NetworkManager::class.java);
expect(NetworkManager.isOnline(context)).andReturn(true);
assertThat(NetworkManager.isOnline(context)).isTrue();

Is there any way around it? I see documentation about mocking static methods, but I haven't managed to make it work.

Thank you!


Solution

  • Try mockObject:

    mockkObject(NetworkClassManager.Companion)
    

    According to this answer: https://github.com/mockk/mockk/issues/136#issuecomment-419879755