如何使用 Mockito.mockStatic 在 kotlin android 中模拟静态方法

Sum*_*rma 6 junit android unit-testing mockito kotlin

如何使用 Mockito.mockStatic 在 kotlin android 中模拟静态方法?

这是我的代码:

    class MyUtilClassTest {
       @Test
       fun testIsEnabled() {
          Mockito.mockStatic(MyUtilClass::class.java, Mockito.CALLS_REAL_METHODS)
                .use { mocked ->
                    mocked.`when`<Boolean> { MyUtilClass.isEnabled() }.thenReturn(true)
                    assertTrue(MyUtilClass.isEnabled())
                }
       }
    }
    
    object MyUtilClass {
       fun isEnabled(): Boolean = false
    }
Run Code Online (Sandbox Code Playgroud)

我收到此异常:

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() 需要一个参数,它必须是“对模拟的方法调用”。例如:when(mock.getArticles()).thenReturn(articles);

此外,出现此错误的原因可能是:

  1. 你存根:final/private/equals()/hashCode() 方法。这些方法不能被存根/验证。不支持在非公共父类上声明的模拟方法。
  2. 在 when() 中,您不会在模拟上调用方法,而是在其他对象上调用方法。

nuh*_*oca 6

如果你用 注释你的函数isEnabled@JvmStatic你不会得到任何错误。正如@Neige指出的,默认情况下,静态函数Kotlin实际上不是静态的bytecode。因此,我们需要用 来标记我们的函数,@JvmStatic以便生成额外的静态getter/setter方法。

object MyUtilClass {
   @JvmStatic
   fun isEnabled(): Boolean = false
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*ige 2

从 JVM 的角度来看MyUtilClass.isEnabled()它不是一个静态类/函数。你可以用它Show Kotlin Bytecode来了解背后的内容

public final class MyUtilClass {
   public static final MyUtilClass INSTANCE;

   public final boolean isEnabled() {
      return false;
   }

   private MyUtilClass() {
   }

   static {
      MyUtilClass var0 = new MyUtilClass();
      INSTANCE = var0;
   }
}
Run Code Online (Sandbox Code Playgroud)