简体   繁体   English

在每个 {... } 块内模拟缺失呼叫

[英]Mockk Missing calls inside every { ... } block

I'm stuck trying to mock some stuff with mockk:我一直试图用 mockk 模拟一些东西:

I have the following setup on gradle我在 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

So I'm writing an androidTest for the SDK and trying to mock Foo.kt .所以我正在为 SDK 编写一个androidTest并尝试模拟Foo.kt There's nothing unusual about Foo class, just direct class Foo(private val someParams) { Foo class 没有什么异常,直接class Foo(private val someParams) {

So using androidTestImplementation "io.mockk:mockk-android:1.8.13" the mock goes:因此,使用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")

I'm always getting the following crash:我总是遇到以下崩溃:

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)

Also tried just to gather information:还试图收集信息:

  • running inside JVM test folder.在 JVM 测试文件夹中运行。 It gets mocked without issues, but I can't run my test as JVM它被嘲笑没有问题,但我无法以 JVM 运行我的测试
  • running androidTest inside Foo module.Foo模块中运行androidTest Got the same crash遇到同样的崩溃
  • using mockkClass(Foo::class).使用 mockkClass(Foo::class)。 Got some crash发生了一些崩溃
  • using annotation @MockK and MockKAnnotations.init(this) .使用注释@MockKMockKAnnotations.init(this) Got some crash.发生了一些崩溃。
  • added Log.d before every { line and inside getData() method and it seems the actual real method from the class is getting called during the mock setup.every {行之前和内部getData()方法中添加了Log.d ,似乎 class 的实际真实方法在模拟设置期间被调用。 That seems super weird to me.这对我来说似乎非常奇怪。

Any idea what's going wrong here?知道这里出了什么问题吗?

edit:编辑:

as requested, full code.根据要求,完整代码。 I'm current working on an isolated project to try to isolate the error, so Foo is just:我目前正在研究一个孤立的项目以尝试隔离错误,所以 Foo 只是:

class Foo {

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

}

and then I have FooTest in androidTest :然后我在 androidTest 中有androidTest

class FooTest {

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

}

It seems to be a Mockk opened issue: https://github.com/mockk/mockk/issues/182这似乎是一个 Mockk 打开的问题: https ://github.com/mockk/mockk/issues/182

2 possible quick fixes ( pick one ): 2 个可能的快速修复(选择一个):

  1. Run the Instrumented Tests in an emulator >= Android-P在模拟器中运行检测测试 >= Android-P
  2. Set Foo class as open (and the method(s) you want to mock too)Foo类设置为打开(以及您要模拟的方法)

Try to check the official guide and see what is missing.尝试检查官方指南,看看缺少什么。

In my case, I tried to mock an extension in Kotlin but missed the mockkStatic就我而言,我试图在 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)

In my case I forgot to spyk the class I was applying every {...} to.在我的情况下,我忘了spykevery {...}应用的课程。 😳 😳

val presenter = spyk(MyPresenter())

every { view.myFun(any()) } returns Unit

In my case, I've missed就我而言,我错过了

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

Make sure the object is really a mock, not the real object.确保对象真的是模拟对象,而不是真实对象。

For instance:例如:

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

就我而言,我尝试使用 mock() 函数来模拟,而不是 mock k () (double k)

My problem was that I used a java class without getters我的问题是我使用了一个没有 getter 的 java 类

public class KeyStorePasswordPair {
    public KeyStore keyStore;
    public String keyPassword;

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

I needed to add getters for the variables to make mockking work:我需要为变量添加吸气剂以使模拟工作:

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

in my case, there was a clash in between @Mock and mockk.就我而言,@Mock 和 mockk 之间存在冲突。 Use either one of them.使用其中之一。 I think in Kotlin, most preferred one is mockk.我认为在 Kotlin 中,最喜欢的是 mockk。

Mockk Missing calls inside every {... } block在每个 {... } 块内模拟缺失呼叫

may also be thrown when you have an every block defined on an object that is not a mockk, for example:当您在不是模拟的 object 上定义了every块时,也可能会抛出,例如:

You define stub behavior like this您像这样定义存根行为

every { foo.getData() } returns DATA

and then try to:然后尝试:

every { DATA.getVersion() } returns VERSION

Where MY_THING and VERSION objects are declared (and instantiated) in the test class.其中MY_THINGVERSION对象在测试 class 中声明(并实例化)。

The error message is not very informative and a bit misleading in that case.在这种情况下,错误消息的信息量不是很大,而且有点误导。

试试这样

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM