Android Studio 北极狐无法使用 mockk 运行 JUnit 配置

标签 android android-studio junit5 mockk

我只是将我的 Android Studio 升级到最新版本。目前我猜我的一些测试类会产生不稳定的测试结果,我想像在 Android Studio 4.2 中一样在 Android Studio 中运行重复模式。但是我发现我得到了以下异常
即使我尝试了一个简单的测试类,我仍然会收到此错误。我使用 Gradle Test runner 运行,它按预期工作,但我无法使用它重复运行测试类以查看我的测试类中是否有任何片状结果
感谢任何评论或建议:)


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
更新:
我只是创建了一个 Hello World 项目并使用上面提到的简单配置。在“Gradle Test Runner”配置中,它可以工作。但是在“JUnit”配置中,发生了同样的错误

最佳答案

android-gradle-plugin在 IDE 项目导入期间删除运行时依赖项。早期的 Android Studio had扩展 JUnit 运行配置类路径以包含运行时依赖项的专用 IDE 功能。现在您必须自己恢复类路径(或者最好避免在 Android 项目中运行 JUnit 配置)。 Android Studio 朝着将一切都委托(delegate)给 Gradle 的方向发展(例如,参见 https://developer.android.com/studio/preview/features#bumblebee-unified-test-runner )。
由于您使用的是 JUnit5,@RepeatedTest(10_000_000)或类似的可能是一个更简单的选择。
TL;博士;MockKAgentFactory可从 io.mockk:mockk-agent-api 获得.我添加了以下内容以使您的示例正常工作:

    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'
诀窍在于 Android Gradle 插件。它构建(至少)2 个类路径:编译和运行时。 IDE Android 插件(在 Android Studio 中)仅从编译类路径导入库(删除运行时条目)。当使用 Gradle 运行器运行测试时,IDE 将执行委托(delegate)给 gradle,而 Gradle 使用 Runtime 类路径调用测试。在 Android Studio 中使用 JUnit 运行测试时,JUnit 使用 IDE 模块的运行时类路径,正如 IDE 所见(它已经没有运行时库,因为它们在导入期间被删除)。检查外部库部分以查看添加到 IDE 项目中的确切内容。
enter image description here
如果项目是普通的 java 项目,IDE 将添加 mockk-agent-jvm及其传递依赖 mockk-agent-api .请注意 mockk-agent-jvmRUNTIME io.mockk:mockk 的依赖关系(见 https://repo1.maven.org/maven2/io/mockk/mockk/1.12.0/mockk-1.12.0.pom)。 android-gradle-plugin在导入期间删除运行时依赖项。从带有 gradle 运行配置的 IDE 运行时,您可以在任何测试方法的开头设置断点并检查堆栈跟踪。完整的测试运行时类路径在 gradle 调用 JUnitRunner 之前的一帧可用。例如。:
enter image description here

关于Android Studio 北极狐无法使用 mockk 运行 JUnit 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68872301/

相关文章:

android - 在哪里可以找到新功能弃用的 Android 功能列表?

java - 等待用户许可继续

java - Android,Java - AutocompleteTextView列表显示在编辑框下

安卓工作室 : 407 Proxy Authentication Required

java - 如何为android studio安装ffmpeg?

android-studio - IntelliJ - 是否可以区分类和接口(interface)?

junit5 - 如何使用在JUnit 5的其他类中定义的@MethodSource

java - 在 N 个线程中并行运行相同的测试 M 次

java - JUnit5 Gradle 插件覆盖默认构建任务

android - 定义应用程序中所有 Activity 要使用的常量 : android