spekframework / spek

A specification framework for Kotlin
Other
2.23k stars 179 forks source link

MockK crashes when running Spek tests from Android Studio #968

Open ntoskrnl opened 3 years ago

ntoskrnl commented 3 years ago

I am trying to use MockK in tests with Spek. Tests run just fine from command line but fail when I run them from the IDE (Android Studio).

There is an issue report in MockK for this, but previously there were similar issues with other test framework plugins (e.g. bug in Kotest plugin). And it was related to the problem in the IDE plugin, not mockk. I think this one is similar and it should be the issue in Spek plugin for Android Studio.

I am using Android Studio 4.1.x with Kotlin plugin 1.4.32 and Spek Framework plugin "2.0.16-IJ2020.2".

Here is a stack trace of the crash (just in case):

io/mockk/proxy/MockKAgentFactory
java.lang.NoClassDefFoundError: io/mockk/proxy/MockKAgentFactory
    at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:185)
    at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:173)
    at io.mockk.MockKKt.every(MockK.kt:712)
    at com.corsano.watch.internal.device.command.SimpleAsyncCommandTest2$1$1$1$1.invoke(SimpleAsyncCommandTest2.kt:50)
    at com.corsano.watch.internal.device.command.SimpleAsyncCommandTest2$1$1$1$1.invoke(SimpleAsyncCommandTest2.kt:25)
    at org.spekframework.spek2.runtime.scope.TestScopeImpl.execute(scopes.kt:136)
    at org.spekframework.spek2.runtime.Executor$execute$result$2$exception$1$job$1.invokeSuspend(Executor.kt:84)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:271)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at org.spekframework.spek2.runtime.TaskRunner$runTask$1.run(executors.kt:26)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ClassNotFoundException: io.mockk.proxy.MockKAgentFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    ... 21 more
ntoskrnl commented 3 years ago

After some digging, I found that adding dependency on mock-agent-jvm artifact fixes the problem. But mockk already has a runtime dependency on it: https://mvnrepository.com/artifact/io.mockk/mockk/1.11.0

raniejade commented 3 years ago

@ntoskrnl Can you attach a sample project here that reproduces the issue? Would help out in debugging.

ntoskrnl commented 3 years ago

Here is a sample project: https://github.com/ntoskrnl/spek2-with-mockk-sample Let me know what I can do to help with the debugging.

For the issue with mockk there is a workaround, but there is also an issue with Spek replacing RunConfiguration for all other tests in the project. It is reported here: https://github.com/spekframework/spek/issues/837 Maybe it has something to do with how SpekRunConfigurationProducer is implemented - it looks like it doesn't actually check if there are other types of tests under the provided path.

raniejade commented 3 years ago

Maybe it has something to do with how SpekRunConfigurationProducer is implemented - it looks like it doesn't actually check if there are other types of tests under the provided path.

Nah, this is something in IJ - IJ will query each plugin for an "action" that can be run in a particular context. It's not the responsibility of Spek's plugin to check for other test types.