unit-testing - MockK - 在顶级 val 上调用模拟/ spy 顶级扩展方法

标签 unit-testing kotlin mocking mockk

在下面的 MWE 中,我尝试验证调用 baz() 是否也会调用另一个对象上的方法。但是,我似乎无法模拟/监视该对象。

MWE:

package com.example

import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import org.junit.jupiter.api.Test

class FooBarTest {
    @Test
    fun `top level fun baz() calls theVal_bar()`() {
        mockkStatic("com.example.FooBarTestKt")
        val spy = spyk(theVal, name = "Hello, Spy!")

        every { theVal } returns spy

        // Should call bar() on the spy, but note that the spy's name is not printed
        baz()

        verify { spy.bar() }
    }
}

class Foo

fun Foo.bar() = println("Foo.bar! name = $this")

val theVal = Foo()

fun baz() = theVal.bar()

此操作失败,因为对 theVal.bar() 的调用获取的是 val 初始值设定项值,而不是模拟值 spy

如何在不更改顶级属性定义的情况下强制使用 spy ?换句话说:我需要一个顶级“常量”,但我也想 mock 它。我可以使用 val theVal get() = Foo() 来解决问题,但它会显着更改代码,因为它每次都会替换 Foo 实例。

使用的版本: - Kotlin 1.3.10 - MockK 1.8.13.kotlin13 - JUnit 5.3.1

错误:

java.lang.AssertionError: Verification failed: call 1 of 1: class com.example.FooBarTestKt.bar(eq(Foo(Hello, Spy!#1)))). Only one matching call to FooBarTestKt(static FooBarTestKt)/bar(Foo) happened, but arguments are not matching:
[0]: argument: com.example.Foo@476b0ae6, matcher: eq(Foo(Hello, Spy!#1)), result: -

最佳答案

哦,当谈到静态和对象模拟以及扩展函数时,这真是疯狂。为了生存,只需将扩展函数视为带有参数的静态函数。

检查,这是有效的,因为 fooInstance 只是作为第一个参数传递的对象:

    mockkStatic("kot.TestFileKt")

    baz()

    val fooInstance = theVal

    verify { fooInstance.bar() }

组合起来不起作用:

    verify { theVal.bar() }

因为它已经过验证。

这也可以工作(正如我所说的 Foo 只是静态方法的第一个参数):

    mockkStatic("kot.TestFileKt")

    baz()

    verify { any<Foo>().bar() }

关于unit-testing - MockK - 在顶级 val 上调用模拟/ spy 顶级扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53502043/

相关文章:

c++ - Catch 单元测试订购

android - 包含CompositeDisposable的测试演示者

unit-testing - 如何在单元测试中使用 mockist 方法避免误报?

flutter - 在 Flutter 上模拟 getExternalStorageDirectory

c# - 我如何模拟 IQueryable<T>

Swift 模拟类

android - 如何在 Kotlin 的抽屉导航 Activity 中添加 OnFragmentInteractionListener?

kotlin - Google Guice 运行时依赖注入(inject)

android - Unresolved reference : Matchers

c# - 多文件删除方法单元测试成功