Kotlin 通过MockConstructor验证深度模拟失败

Kotlin 通过MockConstructor验证深度模拟失败,kotlin,mockk,Kotlin,Mockk,在一个测试中,我想验证当调用该模型的方法时,该模型是否会调用客户机。 被测试的类——模型类——是一个对象单例。() 对客户端的实际调用-DefaultKubernetesClient-发生在kubernetessourcemodel() 模拟工作正常,我看到KubernetesResourceModel.getAllNamespaces()返回模拟时传递的空列表(mockClient(emptyList()))。 不幸的是,核查失败了 验证{anyConstructed().namespace(

在一个测试中,我想验证当调用该模型的方法时,该模型是否会调用客户机。 被测试的类——模型类——是一个对象单例。()

对客户端的实际调用-
DefaultKubernetesClient
-发生在
kubernetessourcemodel
()

模拟工作正常,我看到
KubernetesResourceModel.getAllNamespaces()
返回模拟时传递的空列表(
mockClient(emptyList())
)。 不幸的是,核查失败了

验证{anyConstructed().namespace().list().items}
()

告诉我没有调用
客户端.namespaces().list()
失败:

Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
java.lang.AssertionError: Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
    at io.mockk.impl.recording.states.VerifyingState.failIfNotPassed(VerifyingState.kt:66)
    at io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:42)
    at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalVerify(API.kt:118)
    at io.mockk.MockKKt.verify(MockK.kt:139)
    at io.mockk.MockKKt.verify$default(MockK.kt:136)
    at org.jboss.tools.intellij.kubernetes.model.KubernetesResourceModelTest.should call list namespaces on client(KubernetesResourceModelTest.kt:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch
验证失败:调用3个中的第2个:未调用非名称空间操作(mockkConstructor()的子级)。列表()
java.lang.AssertionError:验证失败:调用3中的第2个:未调用非名称空间操作(mockkConstructor()的子级)。列表()
在io.mock.impl.recording.states.VerifyingState.failIfNotPassed(VerifyingState.kt:66)时
在io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:42)
在io.mock.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
在io.mock.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)上
在io.mock.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
在io.mockk.MockKDsl.internalVerify(API.kt:118)
在io.mockk.MockKKt.verify(mockk.kt:139)
在io.mockk.MockKKt.verify$default处(mockk.kt:136)
在org.jboss.tools.intellij.kubernetes.model.KubernetesResourceModelTest.should调用客户端上的名称空间列表(KubernetesResourceModelTest.kt:32)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.gradle.api.internal.tasks.testing.junit.junitsetclassexecutor.runTestClass(junitsetclassexecutor.java:110)
位于org.gradle.api.internal.tasks.testing.junit.junitsetclassexecutor.execute(junitsetclassexecutor.java:58)
位于org.gradle.api.internal.tasks.testing.junit.junitsetclassexecutor.execute(junitsetclassexecutor.java:38)
位于org.gradle.api.internal.tasks.testing.junit.AbstractJunitestClassProcessor.processTestClass(AbstractJunitestClassProcessor.java:62)
位于org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
位于org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
位于org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
位于org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
位于com.sun.proxy.$Proxy2.processTestClass(未知源)
位于org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
在org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch

知道我遗漏了什么吗?

spyk作用域中的
list()
是否实际引用了
namespaces().list()
?以及其他内容。您正在验证该类的任何构造变量是否应该调用
namespaces().list()
,但您是静态调用该函数(从一个伴随对象)我假设。它实际上可以吗?您能检查名称空间的调用方式是:
verify{anyConstructed().namespaces()}
不,没关系,但我怀疑有其他问题。名称空间函数返回一个类型为
非名称空间操作
的对象,该对象具有我假设的列表函数。尝试在该类上验证该函数,看看它是否有效。我放弃了mockk,原因是我不了解如何验证java客户端库的对象不起作用。使用mockito kotlin实现了同样的功能,效果很好。spyk作用域中的
list()
是否实际引用了
namespaces().list()
?还有一件事。您正在验证任何构造的变量
class Cluster(val client: NamespacedKubernetesClient) {
...
    private fun loadAllNameSpaces(): Sequence<Namespace> {
        return  client.namespaces().list().items.asSequence()
    }
    @Test
    fun `should call list namespaces on client`() {
        // given
        mockClient(emptyList())
        // when
        KubernetesResourceModel.getAllNamespaces()
        // then
        verify { anyConstructed<DefaultKubernetesClient>().namespaces().list().items }
    }
...
    private fun mockClient(namespaces: List<Namespace>) {
        // client.namespaces().list().items.asSequence()
        mockkConstructor(DefaultKubernetesClient::class)
        every { anyConstructed<DefaultKubernetesClient>().namespaces() } returns
                spyk {
                    every { list() } returns
                            spyk {
                                every { items } returns
                                        namespaces
                            }
                    every { watch(any()) } returns
                            mockk()
                }
Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
java.lang.AssertionError: Verification failed: call 2 of 3: NonNamespaceOperation(child of mockkConstructor<DefaultKubernetesClient>()#1).list()) was not called
    at io.mockk.impl.recording.states.VerifyingState.failIfNotPassed(VerifyingState.kt:66)
    at io.mockk.impl.recording.states.VerifyingState.recordingDone(VerifyingState.kt:42)
    at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:60)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalVerify(API.kt:118)
    at io.mockk.MockKKt.verify(MockK.kt:139)
    at io.mockk.MockKKt.verify$default(MockK.kt:136)
    at org.jboss.tools.intellij.kubernetes.model.KubernetesResourceModelTest.should call list namespaces on client(KubernetesResourceModelTest.kt:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch