简体   繁体   English

MockK - 左匹配器的匹配模拟签名失败:[any(), any()]

[英]MockK - Failed matching mocking signature for left matchers: [any(), any()]

I want to implement some UI Tests to assure that the code implemented today works for tomorrow but when trying to see if already UI tests implemented in the past works, it throws this error:我想实施一些 UI 测试以确保今天实施的代码适用于明天,但是当试图查看过去实施的 UI 测试是否有效时,它会抛出此错误:

Caused by: io.mockk.MockKException: Failed matching mocking signature for left matchers: [any(), any()]

This happens on an every {} return Unit line which there's a object file called WakeUpTimeManager , that calls a.set(param1, param2) function and inside that function there are some inline functions which I think it could be causing the problem but I don't know.这发生在every {} return Unit行上,其中有一个名为 WakeUpTimeManager 的对象文件,它调用 a.set(param1, param2)函数,并且在该函数内部有一些内联函数,我认为这可能会导致问题,但我不不知道。 I tried searching on the internet but couldn't find a solution.我尝试在互联网上搜索但找不到解决方案。

Here's the test that throws the error:这是抛出错误的测试:

  @Before
  fun setup() {
    mockkObject(WakeUpTimerManager)
    every { WakeUpTimerManager.set(any(), any()) } returns Unit
  }

Here's the function that is calling on every line这是在every行上调用的函数

  fun set(context: Context, timer: Timer) {
    if (timer.atMillis < System.currentTimeMillis()) {
      return
    }

    if (Preset.findByID(context, timer.presetID) == null) {
      return
    }

    //This is an inline function
    withGson {
      PreferenceManager.getDefaultSharedPreferences(context).edit {
        putString(PREF_WAKE_UP_TIMER, it.toJson(timer))
      }
    }

    //This is an inline function
    withAlarmManager(context) {
      it.setAlarmClock(
        AlarmManager.AlarmClockInfo(timer.atMillis, getPendingIntentForActivity(context)),
        getPendingIntentForService(context, timer)
      )
    }
  }

Question: Why does mockk throw this error?问题:为什么 mockk 会抛出这个错误? What's going on?这是怎么回事? Is there any solution for this?有什么解决办法吗?

try with mockkStatic(WakeUpTimerManager::class) .尝试mockkStatic(WakeUpTimerManager::class) For me mockkObject was not working either, but mockkStatic did对我来说mockkObject也没有工作,但mockkStatic做到了

Can you check that your annotation @ExtendWith is using MockKExtension ?您可以检查您的注释@ExtendWith是否正在使用MockKExtension

@ExtendWith(MockKExtension::class)

Make sure you are using MockK for your mocks as well, I got the same issue while converting from Mockito to MockK .确保您也将MockK用于您的模拟,我在从Mockito转换为MockK时遇到了同样的问题。

In my case I used type cast for any() .就我而言,我对any()使用了类型转换。 I wanted to test that a method viewModel.show(Message()) had invoked.我想测试是否调用了viewModel.show(Message())方法。 But this method is overloaded (has signatures of different types), so I tried to cast parameter any() to Message .但是这个方法是重载的(具有不同类型的签名),所以我尝试将参数any()转换为Message

// show is overloaded method
fun show(resourceId: Int) {}
fun show(text: String) {}
fun show(message: Message) {}

// But it threw the exception.
verify { viewModel.show(any() as Message) }

// This won't work because Message() object will be different 
verify { viewModel.show(Message()) }

Maybe mocking for message will help, but not in my case.也许 mocking 的message会有所帮助,但对我来说不是。

// val message = mockk<Message>()
// every { Message() } returns message
// verify { viewModel.show(message) }

I had to add mockkStatic , because I used an extension method.我必须添加mockkStatic ,因为我使用了扩展方法。 For instance, fun ViewExtension.show() :例如, fun ViewExtension.show()

mockkStatic(ViewExtension::class.java.name + "Kt") // Like "com.example...ViewExtensionKt"

Then mock a behaviour :然后模拟一个行为

every { viewModel.show(Message()) } just Runs
verify { viewModel.show(any() as Message) }

In my case I was using the wrong annotation for mocking dependencies.就我而言,我对 mocking 依赖项使用了错误的注释。

I was using @MockBean from org.springframework.boot.test.mock.mockito.MockBean while I should have been using @MockkBean from com.ninjasquad.springmockk.MockkBean .我正在使用来自org.springframework.boot.test.mock.mockito.MockBean@MockBean ,而我应该使用来自@MockkBeancom.ninjasquad.springmockk.MockkBean

Sometimes, especially with Dagger Hilt and global test modules that replace object instances with Mockk mocks, it's not entirely clear whether one works with the mock or the real object.有时,尤其是对于 Dagger Hilt 和用 Mockk 模拟替换对象实例的全局测试模块,并不完全清楚是使用模拟还是真实对象。 For me it was exactly this - I had a missing dependency, so my real instance was not replaced with the mocked instance, so mockk answered with this really weird error:对我来说正是这样——我缺少依赖项,所以我的真实实例没有被模拟实例替换,所以 mockk 回答了这个非常奇怪的错误:

io.mockk.MockKException: Failed matching mocking signature for

left matchers: [any()]
    at io.mockk.impl.recording.SignatureMatcherDetector.detect(SignatureMatcherDetector.kt:99)
    at io.mockk.impl.recording.states.RecordingState.signMatchers(RecordingState.kt:39)
    at io.mockk.impl.recording.states.RecordingState.round(RecordingState.kt:31)
    at io.mockk.impl.recording.CommonCallRecorder.round(CommonCallRecorder.kt:50)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:63)
    at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
    at io.mockk.MockKDsl.internalVerify(API.kt:119)
    at io.mockk.MockKKt.verify(MockK.kt:149)
    at io.mockk.MockKKt.verify$default(MockK.kt:140)

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

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