javakotlinunit-testingmockitohandler

how to Mock handler in kotlin


   public void myTesting(){
    System.out.println("testing before ");
    new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
        @Override
        public void run() {
            System.out.println("test");
        }
    }, 100);
    System.out.println("testing after ");

}

I am trying to mock the above handler code on kotlin using slot function to return run() function

here are my changes

    mockkStatic(Looper::class)
    mockkStatic(Runnable::class)
    val looper = mockk<Looper>{
        every {
            thread
        } returns Thread.currentThread()
    }

    every {
        Looper.getMainLooper()
    } returns looper

    val Handler = mockk<Handler>(relaxed = true)

    every {
        Handler.postDelayed(capture(slotrunnable) ,100)
    } answers  {
        true
    }

    slotrunnable.captured.run()

    Manager.myTesting()

when i run the test case i am getting lateinit property captured has not been initialized slot


Solution

  • Your system-under-test creates a new Handler:

    new Handler(Looper.getMainLooper()).postDelayed(...
    

    But your unit test code uses every only for a specific mock handler:

    val Handler = mockk<Handler>(relaxed = true)
    
        every {
            Handler.postDelayed(capture(slotrunnable) ,100)
    

    So this will only work for that specific mock object. You may have been misled by naming your object with a capital initial letter, the same name as the class. Don't do that. If you had named it handler instead of Handler, you would then have noticed that your every will affect only that method and not the whole class.

    You should pass a Handler object to your method (dependency injection) instead of creating it inside the method. Then your unit test can pass the mock object to your method under test.