Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mockk failing when targeting Java 21 #1249

Open
3 tasks done
slw546 opened this issue May 14, 2024 · 1 comment
Open
3 tasks done

Mockk failing when targeting Java 21 #1249

slw546 opened this issue May 14, 2024 · 1 comment

Comments

@slw546
Copy link

slw546 commented May 14, 2024

Prerequisites

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

  • I am running the latest version
  • I checked the documentation and found no answer
  • 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 [email protected](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.

  1. Use one of the mockk examples in the readme
  2. Set your kotlin compiler to e.g. in the pom <jvmTarget>21</jvmTarget>, or equivalent for gradle:
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>1.9.23</version>
                <configuration>
                    <jvmTarget>21</jvmTarget>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <phase>compile</phase>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <phase>test-compile</phase>
                    </execution>
                </executions>
            </plugin>
  1. The code will blow up
  2. 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.

  • 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
    }
@BenjaminBeeker
Copy link

Have the same issue with

  • kotlin 2.0.0
  • mockk 1.13.11
  • java 22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants