在kotlin中,无法实例化测试运行器类androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner

问题描述 投票:0回答:1

我开始学习android测试。
我正在尝试使用 Mockk 库和 androidJUnit4 Runner 进行测试。
但实例化失败。
我可能对测试功能有误解。
会有什么问题吗?

当我将测试库/运行器更改为mockito/MockitoJUnitRunner时,没有错误。
当我使用mockito/AndroidJUnit4运行时,会发生同样的错误。
当我在 build.gradle 中更改为 testInstrumentRunner 'androidx.test.runner.AndroidJUnit4'(已弃用)时,
然后使用mockito/AndroidJUnit4运行,在Log.e()处抛出非模拟错误。 所以我将 Log 类模拟为静态,但没有起作用。

import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

import io.mockk.*
import io.mockk.impl.annotations.*
import io.mockk.impl.annotations.MockK
import org.assertj.core.api.Assertions.*


@RunWith(AndroidJUnit4::class)
class StringRetrieverTest {
    @MockK // @Spyk was same.
    lateinit var mContextMock: Context
    
    lateinit var SUT: StringRetriever
    @Before
    fun setup() {
        SUT = StringRetriever(mContextMock)
    }

    @Test
    fun getString_correctParameterPassedToContext(){
        // Arrange
        // Act
        SUT.getString(ID)
        // Assert
        verify { mContextMock.getString(ID) }
    }

    @Test
    fun getString_correctResultReturned() {
        // Arrange
        every { mContextMock.getString(ID) } answers { STRING }
        // Act
        val result = SUT.getString(ID)
        // Assert
        assertThat(result).isEqualTo(STRING)
    }

    companion object {
        const val ID = 10
        const val STRING = "string"
    }
}

我的依赖项在这里。

apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'

android {
    compileSdkVersion 31



    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 31

        testInstrumentationRunner 'androidx.test.ext.junit.runners.AndroidJUnit4'

    }

    buildTypes {
        release {
            postprocessing {
                removeUnusedCode false
                removeUnusedResources false
                obfuscate false
                optimizeCode false
                proguardFile 'proguard-rules.pro'
            }
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.core:core:1.10.1'
    implementation 'androidx.core:core-ktx:1.10.1'
    implementation 'androidx.test.ext:junit-ktx:1.1.5'

    testImplementation 'junit:junit:4.13.2'
    testImplementation("io.mockk:mockk:1.13.5"){
        exclude group:'org.junit.jupiter', module: 'junit-jupiter'
    }
    androidTestImplementation "io.mockk:mockk-android:1.13.5"
    androidTestImplementation 'androidx.test:runner:1.5.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    testImplementation 'androidx.test:runner:1.5.2'
    testImplementation 'androidx.test.ext:junit:1.1.5'

    testImplementation("org.assertj:assertj-core:3.24.2")
    testImplementation 'org.mockito:mockito-core:2.18.3'

}

这里是异常跟踪

java.lang.RuntimeException: Failed to instantiate test runner class androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner


    at androidx.test.ext.junit.runners.AndroidJUnit4.throwInitializationError(AndroidJUnit4.java:129)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:121)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:82)
    at androidx.test.ext.junit.runners.AndroidJUnit4.<init>(AndroidJUnit4.java:56)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
    at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    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 jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:112)
    ... 37 more
Caused by: java.lang.ExceptionInInitializerError
    at androidx.test.internal.runner.RunnerArgs$Builder.<init>(RunnerArgs.java:248)
    at androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner.createRunnerParams(AndroidJUnit4ClassRunner.java:52)
    at androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:48)
    ... 43 more
Caused by: java.lang.RuntimeException: Method allowThreadDiskReads in android.os.StrictMode not mocked. See https://developer.android.com/r/studio-ui/build/not-mocked for details.
    at android.os.StrictMode.allowThreadDiskReads(StrictMode.java)
    at androidx.test.internal.platform.ServiceLoaderWrapper.loadService(ServiceLoaderWrapper.java:45)
    at androidx.test.internal.platform.ServiceLoaderWrapper.loadSingleServiceOrNull(ServiceLoaderWrapper.java:89)
    at androidx.test.internal.platform.ServiceLoaderWrapper.loadSingleService(ServiceLoaderWrapper.java:72)
    at androidx.test.platform.io.PlatformTestStorageRegistry.<clinit>(PlatformTestStorageRegistry.java:46)
    ... 46 more


MockitoJUnitRunner 表现良好,测试已通过。

import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.mockk.*
import io.mockk.impl.annotations.*
import io.mockk.impl.annotations.MockK
import org.assertj.core.api.Assertions.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.MockitoJUnitRunner

//@RunWith(AndroidJUnit4::class)
@RunWith(MockitoJUnitRunner::class)
class StringRetrieverTest {
    @Mock
    lateinit var mContextMock: Context

    lateinit var SUT: StringRetriever
    @Before
    fun setup() {
        SUT = StringRetriever(mContextMock)
    }

    @Test
    fun getString_correctParameterPassedToContext(){
        // Arrange
        // Act
        SUT.getString(ID)
        // Assert
        Mockito.verify(mContextMock).getString(ID)
    }

    @Test
    fun getString_correctResultReturned() {
        // Arrange
        Mockito.`when`(mContextMock.getString(ID)).thenReturn(STRING)
        // Act
        val result = SUT.getString(ID)
        // Assert
        assertThat(result).isEqualTo(STRING)
    }

    companion object {
        const val ID = 10
        const val STRING = "string"
    }
}
android kotlin mockito android-testing
1个回答
0
投票

AndroidJUnit4
适用于仪器测试,不适用于单元测试。 删除
@RunWith(AndroidJUnit4::class)
并重试。 并且不要忘记初始化
lateinit var
属性

© www.soinside.com 2019 - 2024. All rights reserved.