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

Regression when upgrading to io.mockk:mockk:1.12.0 #658

Open
neblung opened this issue Jul 7, 2021 · 3 comments
Open

Regression when upgrading to io.mockk:mockk:1.12.0 #658

neblung opened this issue Jul 7, 2021 · 3 comments

Comments

@neblung
Copy link

neblung commented Jul 7, 2021

Expected Behavior

Code that successfully passes with io.mockk:mockk:1.11.0 should continue to pass when run with io.mockk:mockk:1.12.0

Current Behavior

Running test with 1.12.0 fails with Could not initialize class org.objenesis.strategy.PlatformDescription

Failure Information (for bugs)

Steps to Reproduce

Run below JUnit Test

Context

  • MockK version: 1.12.0
  • OS: Windows
  • Kotlin version: 1.5
  • JDK version: 8
  • JUnit version: 5.7
  • Type of test: unit test
  • gradle version: 7

Failure Logs

Stack trace

// -----------------------[ YOUR STACK STARTS HERE ] -----------------------
Could not initialize class org.objenesis.strategy.PlatformDescription
java.lang.NoClassDefFoundError: Could not initialize class org.objenesis.strategy.PlatformDescription
	at org.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(StdInstantiatorStrategy.java:58)
	at org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:90)
	at io.mockk.proxy.jvm.ObjenesisInstantiator.getOrCreateInstantiator(ObjenesisInstantiator.kt:81)
	at io.mockk.proxy.jvm.ObjenesisInstantiator.instanceViaObjenesis(ObjenesisInstantiator.kt:74)
	at io.mockk.proxy.jvm.ObjenesisInstantiator.instance(ObjenesisInstantiator.kt:42)
	at io.mockk.impl.instantiation.JvmInstantiator$instantiate$2.invoke(JvmInstantiator.kt:16)
	at io.mockk.impl.instantiation.AbstractInstantiator.instantiateViaInstanceFactoryRegistry(AbstractInstantiator.kt:17)
	at io.mockk.impl.instantiation.JvmInstantiator.instantiate(JvmInstantiator.kt:15)
	at io.mockk.impl.JvmMockKGateway$anyValueGeneratorProvider$1.invoke(JvmMockKGateway.kt:60)
	at io.mockk.impl.JvmMockKGateway$anyValueGeneratorProvider$1.invoke(JvmMockKGateway.kt:25)
	at io.mockk.impl.recording.states.RecordingState.call(RecordingState.kt:70)
	at io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
	at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:266)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:23)
	at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:21)
	at java.base/java.lang.System.getenv(Unknown Source)
	at MyTestsKt$whileMockingEnvironment$1$1.invoke(MyTests.kt:12)
	at MyTestsKt$whileMockingEnvironment$1$1.invoke(MyTests.kt:12)
	at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:25)
	at io.mockk.impl.eval.RecordedBlockEvaluator$enhanceWithRethrow$1.invoke(RecordedBlockEvaluator.kt:78)
	at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
	at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:40)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
	at io.mockk.MockKDsl.internalEvery(API.kt:92)
	at io.mockk.MockKKt.every(MockK.kt:98)
	at MyTestsKt.whileMockingEnvironment(MyTests.kt:12)
	at MyTests.test(MyTests.kt:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:135)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:834)
// -----------------------[ YOUR STACK TRACE ENDS HERE ] -----------------------

Minimal reproducible code (the gist of this issue)

// -----------------------[ GRADLE DEFINITIONS ] -----------------------
dependencies {
    testImplementation("io.mockk:mockk:1.12.0")
    testImplementation("io.kotest:kotest-assertions-core-jvm:4.3.1")
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0")
}
// -----------------------[ YOUR CODE STARTS HERE ] -----------------------
import io.kotest.matchers.shouldBe
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.jupiter.api.Test

// method under test
fun <T> whileMockingEnvironment(vararg nameValue: Pair<String, String>, test: () -> T): T {
    try {
        mockkStatic(System::class)
        nameValue.forEach { (name, value) ->
            every { System.getenv(name) } returns value
        }
        return test()
    } finally {
        unmockkStatic(System::class)
    }
}

class MyTests {
    @Test
    fun test() {
        whileMockingEnvironment("FOO" to "BAR") {
            System.getenv("FOO") shouldBe "BAR"
        }
    }
}// -----------------------[ YOUR CODE ENDS HERE ] -----------------------
@stale
Copy link

stale bot commented Sep 7, 2021

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 ask to put an important label.

@stale stale bot added the stale label Sep 7, 2021
@Raibaz Raibaz added important and removed stale labels Sep 7, 2021
@binkley
Copy link

binkley commented Mar 13, 2022

I have the same issue in Mockk 1.12.3 when static mocking System.console().

I do have more detail. It only happens for me when:

  • Static mocking System twice -- it works find when static mocking it just once
  • That version of Mockk depends on Objenesis 3.1
  • Forcing Mockk to use Objenesis 3.2 produces a different problem:
    Caused by: java.lang.NullPointerException
    	at org.objenesis.strategy.PlatformDescription.isThisJVM(PlatformDescription.java:111)
    
  • There's circularity in Objenesis 3.1 (same for 3.2) in using System.getProperty when it was previously static mocked:
    PlatformDescription.java:69
       public static final String JVM_NAME = System.getProperty("java.vm.name");
    
    And PlatformDescription.java:110:
       public static boolean isThisJVM(String name) {
          return JVM_NAME.startsWith(name);
       }
    

I tried overriding "java.vm.name" but without affect (using the excellent System Lambda:

    @Test
    fun `should do nothing for new REPL with no input`() {
        withSystemProperty("java.vm.name", "Mockk", SetOrOverride) {
            mockkStatic(System::class) {
                every { System.console() } returns eofConsole()

                val (exitCode, out, err) = captureRun {
                    mainWithFixedSeed("--test-repl", "--new-repl")
                }
                exitCode shouldBe 0
                out.shouldBeEmpty()
                err.shouldBeEmpty()
            }
        }
    }

    private fun eofConsole(): Console {
        val eofConsole = mockk<Console>()
        val eofReader = mockk<Reader>()
        every { eofConsole.reader() } returns eofReader
        every { eofReader.read() } returns -1
        return eofConsole
    }

A simple check showed it is OK to override "java.vm.name":

fun main() {
    println("I WAS ${System.getProperty("java.vm.name")}")
    System.setProperty("java.vm.name", "Bob")
    println("I AM ${System.getProperty("java.vm.name")}")
}

Prints:

I WAS OpenJDK 64-Bit Server VM
I AM Bob

And defining mock behavior did not work either:

                every { System.getProperty(eq("java.vm.name")) } returns "OpenJDK 64-Bit Server VM Mockk"
                // Also: every { System.getProperty(any()) } returns "OpenJDK 64-Bit Server VM Mockk"

binkley pushed a commit to binkley/skratch that referenced this issue Mar 13, 2022
@binkley
Copy link

binkley commented Mar 13, 2022

It's also worth noting that Mockito flat out refuses to mock System:

org.mockito.exceptions.base.MockitoException: It is not possible to mock static methods of java.lang.System to avoid interfering with class loading what leads to infinite loops

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

No branches or pull requests

3 participants