skip to Main Content

I just upgrade my Android Studio to the latest one. And currently I guess some of my test classes producing flaky test result and I want to run repeat mode in Android Studio as I did in Android Studio 4.2. But I found that I got the following exception

Even I tried with a simple test class i still get this error. I run with Gradle Test runner and it works as expected but i cannot use it to run the test class repeatly to see if there is any flaky result in my test class

Appreciate any comment or advice 🙂


java.lang.NoClassDefFoundError: io/mockk/proxy/MockKAgentFactory

    at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:198)
    at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:186)
    at com.example.testCorrect(Student.kt:24)
    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 com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
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)
    ... 68 more
import io.mockk.mockk
import junit.framework.Assert.assertEquals
import org.junit.jupiter.api.Test

class StudentTest {
    @Test
    fun testCorrect() {
        val mockStudent = mockk<Student>()
        assertEquals(1,1)
    }
}

class Student(
    val name:String
)

enter image description here

Update:

I just create a Hello World project and use the simple configuration as mention above. In "Gradle Test Runner" configuration, it works. But in "JUnit" configuration, same error is occurred

5

Answers


  1. 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)
    

    This is the error part.
    It is saying that class not found exception which means that there is a class mentioned somewhere but if not found or not present.
    Or if you are using an implementation, delete the implementation and put them again.
    This works for me.
    Even I faced same issue.

    Login or Signup to reply.
  2. Two different problem/solutions come to my mind.

    1. You probably forgot to add mockk in your Gradle configuration like below:
    testImplementation "io.mockk:mockk:{version}"
    

    And probably in previous Android Studio, it was being served from Gradle caches.


    1. I don’t know why, but Arctic Fox switches to my custom installed JDK (1.8) every time I open a project for the first time and I face some CNF exceptions in my builds. After changing it to the embedded JDK, everything works as it should. You can go to Preferences -> Build, Execution -> Build Tools -> Gradle and change Gradle SDK to the Embedded JDK. As I can see in your screenshot, you’re also running the tests using a custom installed JDK 11. However, mockk is not inside JDK so I guess my first suggestion might suits better.

    Gradle JDK

    Login or Signup to reply.
  3. You’re missing the test runner annotation

    @RunWith(MockitoJUnitRunner::class)
    

    also you need to check your build.gradle(app) file for the following

    testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
    testImplementation 'org.mockito:mockito-inline:3.8.0'
    
    Login or Signup to reply.
  4. Can you try adding this to your app level build.gradle:

    testOptions {
        unitTests.all {
            useJUnitPlatform()
        }
    }
    
    Login or Signup to reply.
  5. android-gradle-plugin removes runtime dependencies during IDE project import. Earlier days Android Studio had dedicated IDE feature that extended JUnit run configuration classpath to include runtime dependencies. Now you have to recover classpath yourself (or better avoid JUnit run configuration in Android projects). Android Studio moves to a direction that everything should be delegated to Gradle (e.g. see https://developer.android.com/studio/preview/features#bumblebee-unified-test-runner).

    Since you are using JUnit5, @RepeatedTest(10_000_000) or the like might be an easier option.

    TL; DR;

    MockKAgentFactory is available from io.mockk:mockk-agent-api. I added the following to make your example work:

        testImplementation "io.mockk:mockk:1.12.0"
        testImplementation "io.mockk:mockk-agent-jvm:1.12.0"
        testImplementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.5.30'
    

    The trick is in Android Gradle Plugin. It builds (at least) 2 classpathes: compile and runtime. IDE Android Plugin (in Android Studio) imports only libraries from Compile classpath (runtime entries are removed). When running tests with the Gradle runner, IDE delegates execution to gradle, and Gradle invokes tests with the Runtime classpath. When running tests with JUnit in Android Studio, JUnit uses runtime classpath of an IDE module as it’s seen by the IDE (which already has no runtime libs because they were removed during import). Check External Libraries section to see what exactly is added to the IDE project.
    enter image description here

    If the project was a regular java project, IDE would add mockk-agent-jvm and its transitive dependency mockk-agent-api. Note that mockk-agent-jvm is a RUNTIME dependency of io.mockk:mockk (see https://repo1.maven.org/maven2/io/mockk/mockk/1.12.0/mockk-1.12.0.pom). android-gradle-plugin removes runtime dependencies during import. When running from IDE with gradle run configuration, you can set a breakpoint in the beginning of any test method and check the stacktrace. Full test runtime classpath is available one frame before JUnitRunner is invoked by gradle. E.g.:
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search