【问题标题】:Mockk Missing calls inside every { ... } block模拟每个 { ... } 块内的缺失呼叫
【发布时间】:2019-04-22 19:33:44
【问题描述】:

我一直在尝试用 mockk 模拟一些东西:

我在 gradle 上有以下设置

root:
  |-- App (just a sample app for the SDK)
  |-- SDK (SDK we develop) << apply plugin: 'com.android.library'
       |-- SDKimpl.kt
  |-- Foo (wrapper around a .jar library) << apply plugin: 'com.android.library'
       |-- Foo.kt

所以我正在为 SDK 编写 androidTest 并尝试模拟 Foo.kt。 Foo类没有什么不寻常的,直接class Foo(private val someParams) {

所以使用androidTestImplementation "io.mockk:mockk-android:1.8.13" 模拟:

val mock: Foo = mockk()
// val mock: Foo = mockkClass(Foo::class) // also tried this
every { mock.getData() } returns listOf("1", "2", "3")

我总是遇到以下崩溃:

io.mockk.MockKException: Missing calls inside every { ... } block.
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:42)

也只是为了收集信息:

  • 在 JVM 测试文件夹中运行。它被嘲笑没有问题,但我无法以 JVM 运行我的测试
  • Foo 模块内运行androidTest。遇到同样的崩溃
  • 使用 mockkClass(Foo::class)。发生了一些崩溃
  • 使用注释@MockKMockKAnnotations.init(this)。发生了一些崩溃。
  • every { 行之前和getData() 方法内添加了Log.d,并且似乎在模拟设置期间调用了该类的实际真实方法。我觉得这很奇怪。

知道这里出了什么问题吗?

编辑:

根据要求,完整代码。我目前正在开发一个隔离项目以尝试隔离错误,所以 Foo 只是:

class Foo {

    fun getData(): String {
        Log.d(TAG, "invoked foo.getData()")
        return "trolololo"
    }

}

然后我在androidTest 中有FooTest:

class FooTest {

    @Test
    fun mock_foo() {
        val foo = mockk<Foo>()
        every { foo.getData() } returns "zero"
        assertEquals("zero", foo.getData())
    }

}

【问题讨论】:

  • 发布你的 Foo.kt 完整代码
  • @sasikumar 我正在开发一个单独的测试项目以尝试隔离错误。所以 Foo 上真的什么都没有,编辑了这个问题。都在那里。
  • 任何可用的解决方案?
  • @HardikBambhania 我刚刚标记了解决方案

标签: android kotlin mocking mockk


【解决方案1】:

这似乎是一个 Mockk 打开的问题:https://github.com/mockk/mockk/issues/182

2 个可能的快速修复(选择一个):

  1. 在模拟器中运行检测测试 >= Android-P
  2. Foo 类设置为开放(以及您要模拟的方法)

【讨论】:

    【解决方案2】:

    尝试检查official guide,看看缺少什么。

    就我而言,我尝试在 Kotlin 中模拟一个扩展,但错过了 mockkStatic

    fun Date.asMyTime() : DateTime = DateTime(this, DateTimeZone.getDefault())
    
    mockkStatic("packageName.FileNameKt") // This is what I was missing
    every {
        DateTime().asMyTime()
    } returns mock(DateTime::class.java)
    

    【讨论】:

      【解决方案3】:

      在我的例子中,我忘记了 spyk 我申请 every {...} 的课程。 ?

      val presenter = spyk(MyPresenter())
      
      every { view.myFun(any()) } returns Unit
      

      【讨论】:

      • 我们可以将any() 添加到spyk
      • @AkshayHazari spyk 用于为“真实”对象添加模拟和验证能力。可以用mockks 完成的任何事情都可以在spyk'd 对象上完成,例如every{}verify{} 等。
      【解决方案4】:

      就我而言,我错过了

      @Before
      fun setUp() {
          MockKAnnotations.init(this)
      }
      

      【讨论】:

        【解决方案5】:

        确保对象确实是模拟对象,而不是真实对象。

        例如:

        - Sdk sdk = Sdk()
        + Sdk sdk = mockk()
          every { sdk.crypto } returns mockk()
        

        【讨论】:

          【解决方案6】:

          在我的例子中,我尝试使用 mock() 函数来模拟而不是 mockk() (double k)

          【讨论】:

            【解决方案7】:

            我的问题是我使用了一个没有 getter 的 java 类

            public class KeyStorePasswordPair {
                public KeyStore keyStore;
                public String keyPassword;
            
                public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
                    this.keyStore = keyStore;
                    this.keyPassword = keyPassword;
                }
            }
            

            我需要为变量添加 getter 以使模拟工作:

            public class KeyStorePasswordPair {
                public KeyStore getKeyStore() {
                    return keyStore;
                }
            
                public String getKeyPassword() {
                    return keyPassword;
                }
            
                private KeyStore keyStore;
                private String keyPassword;
            
                public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
                    this.keyStore = keyStore;
                    this.keyPassword = keyPassword;
                }
            }
            
            

            【讨论】:

              【解决方案8】:

              这样试试

              `when`(mock.getData()).thenReturn(listOf("1", "2", "3"))
              

              【讨论】:

                猜你喜欢
                • 2021-04-07
                • 1970-01-01
                • 2013-12-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多