繁体   English   中英

Kotlintest with Mockk 如何清除验证计数

[英]Kotlintest with Mockk How to clear verify count

所以我有以下代码:

When("SMS with location update command is received") {
        every {
            context.getString(R.string.location_sms, any(), any(), any(), any())
        } returns "loc"
        mainServiceViewModel.handleSms(SmsMessage("123", "location"))

        Then("SMS with location is sent to specified phone number") {
            verify(exactly = 1) {
                smsRepository.sendSms("+123", "loc")
            }
        }
    }

    When("motion is detected") {

        Then("information SMS is sent to specified phone number") {
            verify(exactly = 1) {
                smsRepository.sendSms("+123", any())
            }
        }
    }

它的问题是,两种情况都通过了,即使第二个没有做任何动作。 我希望第二种情况会失败,因为甚至没有调用 sendSms 方法。

  1. 如何重置 smsRepository 验证计数?
  2. 如何在每个 When 案例之前重置该计数?

这可能是因为 KotlinTest 与 JUnit 在被视为测试的内容以及创建Spec实例时不同。

KotlinTest的默认行为是在每次执行时创建Spec的单个实例。 因此,您的模拟不会在执行之间重置,因为您可能在class level创建了它们。


要解决此问题,您可以做的是在测试中进行mockk ,或者将隔离模式更改为每次执行测试时都创建Spec 模式

默认的isolationModeIsolationMode.SingleInstance 您可以通过覆盖isolationMode功能在Spec本身上更改它:

class MySpec : BehaviorSpec() {

    init {
        Given("XX") { 
            Then("YY") // ...
        }
    }

    override fun isolationMode() = IsolationMode.InstancePerTest

}

您也可以在 ProjectConfig 中更改它。 如果您需要有关如何在那里执行此操作的说明, 请查看 ProjectConfig 上的文档


另一种方法是清除afterTest方法上的afterTest

class MySpec : BehaviorSpec() {

    init {
        Given("XX") { 
            Then("YY") // ...
        }
    }

    override fun afterTest(testCase: TestCase, result: TestResult) {
        clearAllMocks()
    }

}

但我不确定这在您的用例中如何工作。

  1. 您应该尝试提供用于重置模拟状态的各种clear方法。 查看此相关问题MockK 的文档以获取更多信息。

  2. 检查有关测试侦听器文档 基本上,每个测试规范类都提供了像beforeEach这样的生命周期方法,你可以重写这些方法来重置你的beforeEach (使用clear )。 当您扩展 BehaviourSpec 时,您应该能够只覆盖这些方法,否则请确认如何针对不同的测试样式执行此操作以避免混淆。

要在每次测试后清除模拟,您可以提供一个项目范围的侦听器:

import io.kotest.core.listeners.TestListener
import io.kotest.core.spec.AutoScan
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.mockk.clearAllMocks

@AutoScan
class MockkClearingTestListener : TestListener {
    override suspend fun afterEach(testCase: TestCase, result: TestResult) = clearAllMocks()
}

这适用于例如WordSpec每个叶子,并且也适用于BehaviorSpec

暂无
暂无

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

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