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
Expected Behavior
Demo code from the mockk readme should work when targeting jvm 21 in kotlin-maven-plugin
Current Behavior
Using the demo code blocks, i.e.
class Adder {
fun addOne(num: Int) = num + 1
}
@Test
fun test() {
val adder = io.mockk.mockk<Adder>()
io.mockk.every { adder.addOne(1) } returns -1
io.mockk.every { adder.addOne(3) } answers { callOriginal() }
assertEquals(-1, adder.addOne(2))
assertEquals(4, adder.addOne(3)) // original function is called
}
Mockk methods do not appear to return a mock when called only under JVM 21. I.e. if I target up to 20:
io.mockk.mockk<Adder>(relaxed = false).addOne() will throw an MockK exception as expected: no answer found for com.Testy$Adder@1931d99.addOne(1) among the configured answers: ()
Calling the same code with a JVM target of 21 throws no exceptions. In effect I seem to have a concrete instance of the class, or at least a relaxed mock, as I can call addOne and get a correct response - i.e it's calling the underlying method. However, it cannot be used as a proper mock and will instead blow up in the every block:
io.mockk.MockKException: Failed matching mocking signature for
left matchers: [any()]
at io.mockk.impl.recording.SignatureMatcherDetector.detect(SignatureMatcherDetector.kt:97)
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:62)
at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalEvery(API.kt:94)
at io.mockk.MockKKt.every(MockK.kt:143)
at com.vortexa.homework.metrics.Testy.test(Testy.kt:20)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
...
Indeed if you add a verify block it'll blow up looking suspiciously like it can't find a mock at all inside the verify: io.mockk.MockKException: Missing calls inside verify { ... } block, equally on Objects, you'll get the Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock - all implying the return is no longer a proper mock under 21.
Failure Information (for bugs)
Steps to Reproduce
Please provide detailed steps for reproducing the issue.
Use one of the mockk examples in the readme
Set your kotlin compiler to e.g. in the pom <jvmTarget>21</jvmTarget>, or equivalent for gradle:
Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
MockK version: 1.13.10
OS: OSx
Kotlin version: 1.9.10
JDK version: Azul Zulu 21 for both. Change the kotlin compiler target between 20 and 21 to trigger.
JUnit version: 4.13.2
Type of test: unit test
Stack trace
io.mockk.MockKException: Failed matching mocking signature for
left matchers: [any()]
at io.mockk.impl.recording.SignatureMatcherDetector.detect(SignatureMatcherDetector.kt:97)
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:62)
at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
at io.mockk.MockKDsl.internalEvery(API.kt:94)
at io.mockk.MockKKt.every(MockK.kt:143)
at com.vortexa.homework.metrics.Testy.test(Testy.kt:20)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Minimal reproducible code (the gist of this issue)
package com.vortexa.homework.metrics
import org.junit.Assert.assertEquals
import org.junit.Test
class Testy {
class Adder {
fun addOne(num: Int) = num + 1
}
@Test
fun test() {
val adder = io.mockk.mockk<Adder>
io.mockk.every { adder.addOne(1) } returns -1
io.mockk.every { adder.addOne(3) } answers { callOriginal() }
assertEquals(-1, adder.addOne(2))
assertEquals(4, adder.addOne(3)) // original function is called
}
Prerequisites
Please answer the following questions for yourself before submitting an issue.
Expected Behavior
Demo code from the mockk readme should work when targeting jvm 21 in kotlin-maven-plugin
Current Behavior
Using the demo code blocks, i.e.
Mockk methods do not appear to return a mock when called only under JVM 21. I.e. if I target up to 20:
io.mockk.mockk<Adder>(relaxed = false).addOne()
will throw an MockK exception as expected:no answer found for com.Testy$Adder@1931d99.addOne(1) among the configured answers: ()
Calling the same code with a JVM target of 21 throws no exceptions. In effect I seem to have a concrete instance of the class, or at least a relaxed mock, as I can call addOne and get a correct response - i.e it's calling the underlying method. However, it cannot be used as a proper mock and will instead blow up in the every block:
Indeed if you add a verify block it'll blow up looking suspiciously like it can't find a mock at all inside the verify:
io.mockk.MockKException: Missing calls inside verify { ... } block
, equally on Objects, you'll get theMissing mocked calls inside every { ... } block: make sure the object inside the block is a mock
- all implying the return is no longer a proper mock under 21.Failure Information (for bugs)
Steps to Reproduce
Please provide detailed steps for reproducing the issue.
Use one of the mockk examples in the readme
Set your kotlin compiler to e.g. in the pom
<jvmTarget>21</jvmTarget>
, or equivalent for gradle:The code will blow up
Set the target to 20 and the same code will work
Context
Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
Stack trace
Minimal reproducible code (the gist of this issue)