Mockk: Mocking error when mocking a spy method on an interface within androidTest unit test

Created on 19 Feb 2019  路  3Comments  路  Source: mockk/mockk

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • [X] I am running the latest version
  • [X] I checked the documentation and found no answer
  • [X] I checked to make sure that this issue has not already been filed

Explanation/Details

I have an interface and implementation, in Kotlin, and I am trying to validate behavior of function A, which uses function B internally. I am trying to mock function B by using a spy obj. of the implementation class.

Example Class + Unit Test

interface MockkTest {
    fun canDoThingA(name: String): Boolean

    fun canDoThingB(name: String, amount: Double): Boolean
}
class MockkTestImpl(): MockkTest {
    override fun canDoThingA(name: String): Boolean {
        if (name.isEmpty()) {
            return false
        }

        // Want to mock this method usage here
        if (!canDoThingB(name, 1.0)) {
            return false
        }

        return name == "Test"
    }

    override fun canDoThingB(name: String, amount: Double): Boolean {
        return false
    }
}



md5-b6d38f7b9f29caf1198d9852c0ccdbac



class MockkTestImplTest {

    val thingToTest: MockkTest = MockkTestImpl()

    @Test
    fun canDoThingA_shouldFail() {
        val expected = false

        // thingToTest.canDoThingB(...) returns false by default, so this test should fail.
        val actual = thingToTest.canDoThingA("this is a valid name")

        Truth.assertThat(actual).isEqualTo(expected)
    }

    @Test
    fun canDoThingA_shouldSucceed() {
        val spyThing = spyk(thingToTest)

        val expected = true

        // Changing this method to return true should cause spyThing.canDoThingA(...) to return true
        every { spyThing.canDoThingB(any(), any()) } answers { true }

        val actual = spyThing.canDoThingA("this is a valid name")

        Truth.assertThat(actual).isEqualTo(expected)
    }
}



md5-8eadc90e95aa653df78b2115b36bf43d



There was 1 failure:
1) canDoThingA_shouldSucceed({package removed}.MockkTestImplTest)
io.mockk.MockKException: Failed matching mocking signature for

left matchers: [any(), any()]
    at io.mockk.impl.recording.SignatureMatcherDetector.detect(SignatureMatcherDetector.kt:99)
    at io.mockk.impl.recording.states.RecordingState.signMatchers(RecordingState.kt:38)
    at io.mockk.impl.recording.states.RecordingState.round(RecordingState.kt:30)
    at io.mockk.impl.recording.CommonCallRecorder.round(CommonCallRecorder.kt:45)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:47)
    at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:25)
    at io.mockk.MockKDsl.internalEvery(API.kt:93)
    at io.mockk.MockKKt.every(MockK.kt:104)
bug important

Most helpful comment

@oleksiyp Stale bot isn't very helpful closing issues that haven't been fixed...

All 3 comments

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just put an important tag.

@oleksiyp Stale bot isn't very helpful closing issues that haven't been fixed...

I have an issue similar to this, also in an androidTest. I cannot seem to spyk(..) or mockk() any of the constituents of my integration test without

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:59)
at io.mockk.impl.eval.VerifyBlockEvaluator.verify(VerifyBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalVerify(API.kt:118)
at io.mockk.MockKKt.verify(MockK.kt:146)
at io.mockk.MockKKt.verify$default(MockK.kt:143)
at com.syf.synchronysdk.integration.architecture.ArchitectureIntegrationTest.fragment_resumed(ArchitectureIntegrationTest.kt:72)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)

For example, if I have an object that I'm spyking / mockking, that implements interface Renderer<StateT: State> { fun render(state: StateT) }, it gives the above error when I call verify { testViewComponent.render(any()) }

EDIT: I managed to fix this for myself. It seems it had to do with a couple of things.
1) The class I was wrapping with spyk needed to be an open class
2) I needed to make sure the spyk was being provided and operated on, instead of keeping a reference and wrapping it in a spyk after the fact.

Was this page helpful?
0 / 5 - 0 ratings