Kotlintest与Mockk如何清除验证计数

所以我有以下代码:

When("SMS with location update command is received") {
        every {
            context.getString(R.string.location_sms,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. 如何在每次“何时”案例之前重置该计数?
lyc5748056 回答:Kotlintest与Mockk如何清除验证计数

  1. 您应该尝试提供的各种clear方法来重置模拟状态。检查this related questionMockK's docs以获得更多信息。

  2. 选中documentation about test listeners。基本上,每个测试规范类都提供诸如beforeEach之类的生命周期方法,您可以重写这些生命周期方法以重置模拟(使用clear)。在扩展BehaviourSpec时,您应该能够覆盖这些方法,否则请针对不同的testing styles确认如何做到这一点,以免造成混淆。

,

这可能是由于KotlinTest与JUnit在被认为是测试以及创建Spec实例时有所不同。

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


要解决此问题,您可以做的是在测试内部进行mockk,或者将isolation mode更改为每次执行测试都会创建Spec的内容。 / p>

默认isolationModeIsolationMode.SingleInstance。您可以通过覆盖Spec函数在isolationMode本身上进行更改:

class MySpec : BehaviorSpec() {

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

    override fun isolationMode() = IsolationMode.InstancePerTest

}

您也可以在ProjectConfig中对其进行更改。如果您需要在此处进行操作的说明,请check the docs on ProjectConfig


一种替代方法是清除afterTest方法上的模拟:

class MySpec : BehaviorSpec() {

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

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

}

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

,

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

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工作。

本文链接:https://www.f2er.com/2878684.html

大家都在问