15

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:

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. 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

  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? What's going on? Is there any solution for this?

Barrufet
  • 495
  • 1
  • 11
  • 33

6 Answers6

9

try with mockkStatic(WakeUpTimerManager::class). For me mockkObject was not working either, but mockkStatic did

M. Wojcik
  • 2,301
  • 3
  • 23
  • 31
9

In my case I was using the wrong annotation for mocking dependencies.

I was using @MockBean from org.springframework.boot.test.mock.mockito.MockBean while I should have been using @MockkBean from com.ninjasquad.springmockk.MockkBean.

Thomas Negash
  • 401
  • 4
  • 5
  • 1
    Good catch!!! I had the same problem due to a simple typo. MockkBean and MockBean just look so similar when working late you don't notice the difference! – Dani Jul 19 '23 at 16:43
2

In my case I was mocking a Companion object method using

mockkStatic(ObjectName::class)
every { ObjectName.method() } returns blah

What did the trick was

mockkObject(ObjectName)

Source - https://github.com/mockk/mockk/issues/136

Eric
  • 2,573
  • 1
  • 23
  • 19
1

In my case I used type cast for any(). I wanted to test that a method viewModel.show(Message()) had invoked. But this method is overloaded (has signatures of different types), so I tried to cast parameter any() to 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.

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

I had to add mockkStatic, because I used an extension method. For instance, 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) }
CoolMind
  • 26,736
  • 15
  • 188
  • 224
1

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. 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:

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)
Thomas Keller
  • 5,933
  • 6
  • 48
  • 80
0

Using mockkStatic along with casting of any() to String worked for me.

Eg -

        mockkStatic(InvolvedClass::class)
        every { InvolvedClass.involvedMethod( any() as String,  any() as String) } returns  mockk()