【问题标题】:How to use Mockito.mockStatic for mocking static methods in kotlin android如何使用 Mockito.mockStatic 在 kotlin android 中模拟静态方法
【发布时间】:2020-12-10 15:19:47
【问题描述】:

如何使用 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
    }

我遇到了这个异常:

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

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

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

【问题讨论】:

标签: android unit-testing kotlin junit mockito


【解决方案1】:

从 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;
   }
}

【讨论】:

    【解决方案2】:

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

    object MyUtilClass {
       @JvmStatic
       fun isEnabled(): Boolean = false
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2010-09-14
      • 2018-10-18
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多