Mockk 无法验证以数据类作为参数的 lambda

问题描述 投票:0回答:1
import io.mockk.verify
import org.junit.jupiter.api.Test

class DummyTest {

    @Test
    fun `dummy test to show issue with mockk`() {
        val lambdaFunc: (SomeDataClass) -> Unit = { }
        dummyFunc(lambdaFunc)

        verify(exactly = 1) {
            lambdaFunc(any<SomeDataClass>(any()))     // using lambdaFunc(any<SomeDataClass>(any<AnotherDataClass>())) gives Argument type mismatch error
        }
    }
}

data class AnotherDataClass(val arg1: String, val arg2: String)

sealed class SomeSealedClass {
    data class SomeDataClass(val anotherDataClass: AnotherDataClass): SomeSealedClass()
}

fun dummyFunc(
    onEvent: (SomeDataClass) -> Unit
) {
    onEvent(SomeDataClass(AnotherDataClass("arg1", "arg2")))
}

当我运行上述命令时,出现以下错误:

Receiver class kotlin.reflect.KClass$Subclass1 does not define or inherit an implementation of the resolved method 'abstract boolean isValue()' of interface kotlin.reflect.KClass.
java.lang.AbstractMethodError: Receiver class kotlin.reflect.KClass$Subclass1 does not define or inherit an implementation of the resolved method 'abstract boolean isValue()' of interface kotlin.reflect.KClass.
    at io.mockk.impl.recording.JvmSignatureValueGenerator.signatureValue(JvmSignatureValueGenerator.kt:19)
    at io.mockk.impl.recording.states.RecordingState.matcher(RecordingState.kt:46)
    at io.mockk.impl.recording.CommonCallRecorder.matcher(CommonCallRecorder.kt:52)
    at io.mockk.MockKMatcherScope.match(API.kt:695)
    at io.mockk.MockKMatcherScope.any(API.kt:745)
    at com.sarim.puzzle.data.usecase.DummyTest.dummy_test_to_show_issue_with_mockk$lambda$0(DummyTest.kt:16)
    at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:24)
    at io.mockk.impl.eval.RecordedBlockEvaluator$enhanceWithRethrow$1.invoke(RecordedBlockEvaluator.kt:76)
    at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:39)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalVerify(API.kt:120)
    at io.mockk.MockKKt.verify(MockK.kt:218)
    at io.mockk.MockKKt.verify$default(MockK.kt:209)
    at com.sarim.puzzle.data.usecase.DummyTest.dummy test to show issue with mockk(DummyTest.kt:15)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at java.base/java.util.ArrayList.forEach(Unknown Source)
    at java.base/java.util.ArrayList.forEach(Unknown Source)

我见过的大多数解决方案都不处理嵌套数据类。我什至不确定Mockk是否支持这种验证。

罪魁祸首就在这里:

verify(exactly = 1) { lambdaFunc(any<SomeDataClass>(any()))     // using lambdaFunc(any<SomeDataClass>(any<AnotherDataClass>())) gives Argument type mismatch error }

但我不确定如何更改此行来验证行为

android kotlin unit-testing mockk mockk-verify
1个回答
0
投票

好吧,我终于找到了一种方法来完成这项工作。我再次重新发布我的代码的修改版本

import com.sarim.puzzle.data.usecase.SomeSealedClass.SomeDataClass
import com.sarim.puzzle.data.usecase.SomeSealedClass.SomeOtherDataClass
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Test

class DummyTest {

    @Test
    fun `dummy test to show issue with mockk`() {
        val lambdaFunc1: (SomeSealedClass) -> Unit = mockk(relaxed = true)
        val lambdaFunc2: (SomeSealedClass) -> Unit = mockk(relaxed = true)
        dummyFunc(lambdaFunc1, lambdaFunc2)

        verify(exactly = 1) {
            lambdaFunc1(
                withArg {
                    it is SomeOtherDataClass && it.arg == "arg"
                }
            )
        }

        verify(exactly = 1) {
            lambdaFunc2(
                withArg {
                    it is SomeDataClass && it.anotherDataClass.arg1 == "arg1" && it.anotherDataClass.arg2 == "arg2"
                }
            )
        }
    }
}

data class AnotherDataClass(val arg1: String, val arg2: String)

sealed class SomeSealedClass {
    data class SomeDataClass(val anotherDataClass: AnotherDataClass): SomeSealedClass()
    data class SomeOtherDataClass(val arg: String): SomeSealedClass()
}

fun dummyFunc(
    onEvent1: (SomeSealedClass) -> Unit,
    onEvent2: (SomeSealedClass) -> Unit
) {
    onEvent1(SomeOtherDataClass("arg"))
    onEvent2(SomeDataClass(AnotherDataClass("arg1", "arg2")))
}

基本上,您需要模拟 lambda,然后使用 withArg 首先验证您传入的数据类的类型,如果该数据类有更多参数,您也可以验证这些参数。

© www.soinside.com 2019 - 2024. All rights reserved.