How to Mock Handler(Looper) on kotlin unit test

357 Views Asked by At
 Handler(Looper.getMainLooper()).postDelayed(
            {
                println("inside the looper")
                val firmwareVersion = managerService.getDeviceFirmwareVersion();
                fwStatus = if (!firmwareVersion.isNullOrEmpty()) "$versionValue $firmwareVersion" else "--"
                UpdateManagerInstance.disconnectFromUpdateService()
            }, 2000)

is there anyway to tackle this block of code on Unit test kotlin mockito?

2

There are 2 best solutions below

2
On BEST ANSWER

In Android unit testing, you might need to mock the Handler or Looper to test code that involves background threads or delayed operations. Here's how you can mock a Handler and Looper in Kotlin unit tests:

  1. Use a Testing Framework: To mock a Handler and Looper effectively, you can use a testing framework like Mockito, which allows you to create mock objects. To use Mockito in your Android project, you need to include the Mockito dependency in your project's build.gradle file:

test implementation 'org.mockito:mockito-core:x.y.z'

Replace 'x.y.z' with the latest version of Mockito available.

  1. Mocking Handler and Looper: Assuming you have a class with a Handler or Looper dependency that you want to test, you can mock these objects in your unit test. For example, let's say you have a class with a Handler dependency:
class MyHandlerClass(private val handler: Handler) {
    // Your code that uses the Handler
}

In your unit test, you can mock the Handler using Mockito:

import android.os.Handler
import org.junit.Test
import org.mockito.Mockito

class MyHandlerClassTest {
    @Test
    fun testHandlerFunction() {
        // Create a mock Handler
        val handler = Mockito.mock(Handler::class.java)

        // Create an instance of your class with the mock Handler
        val myHandlerClass = MyHandlerClass(handler)

        // Your test logic here
    }
}

By creating a mock Handler with Mockito, you can control its behavior during your tests.

  1. Mocking Looper: If your code directly depends on the Looper, you can mock the Looper as well. Here's an example:
import android.os.Handler
import android.os.Looper
import org.junit.Test
import org.mockito.Mockito

class MyLooperClassTest {
    @Test
    fun testLooperFunction() {
        // Create a mock Looper
        val looper = Mockito.mock(Looper::class.java)

        // Create a mock Handler with the mock Looper
        val handler = Handler(looper)

        // Create an instance of your class with the mock Handler
        val myLooperClass = MyHandlerClass(handler)

        // Your test logic here
    }
}

Mocking the Looper in this way allows you to control the behavior of the Handler since Handler relies on the provided Looper.

Remember that Mockito allows you to define the behavior of these mock objects by using its when and thenReturn methods. This way, you can simulate the expected behavior of the Handler or Looper during your unit tests.

0
On

Sample UseCase

 val handler = mock(Handler::class.java)
`when`(handler.post(any())).thenAnswer { invocation ->
                invocation.getArgument(0, Runnable::class.java).run()
                true
 }