为什么 Robolectric 4.4 打破了我的 MockK 测试

Hec*_*tor 8 android robolectric mockk

我当前的 Android 应用程序在其单元中使用 MockK

我所有的测试都按预期运行 testImplementation 'org.robolectric:robolectric:4.3'

但是,当我将版本增加到 testImplementation 'org.robolectric:robolectric:4.4'

我所有的测试都失败了,但有以下例外:-

java.lang.IllegalAccessError: tried to access class androidx.lifecycle.LiveData$ObserverWrapper from class androidx.lifecycle.LiveData$Subclass1

    at androidx.lifecycle.LiveData$Subclass1.<clinit>(Unknown Source)
    at sun.reflect.GeneratedSerializationConstructorAccessor7.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
    at io.mockk.proxy.jvm.ObjenesisInstantiator.instanceViaObjenesis(ObjenesisInstantiator.kt:75)
    at io.mockk.proxy.jvm.ObjenesisInstantiator.instantiateViaProxy(ObjenesisInstantiator.kt:66)
    at io.mockk.proxy.jvm.ObjenesisInstantiator.instance(ObjenesisInstantiator.kt:29)
    at io.mockk.proxy.jvm.ProxyMaker.instantiate(ProxyMaker.kt:75)
    at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:42)
    at io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:34)
    at io.mockk.impl.instantiation.AbstractMockFactory.newProxy$default(AbstractMockFactory.kt:29)
    at io.mockk.impl.instantiation.AbstractMockFactory.temporaryMock(AbstractMockFactory.kt:127)
    at io.mockk.impl.recording.states.RecordingState$call$retValue$1.invoke(RecordingState.kt:72)
    at io.mockk.impl.instantiation.JvmAnyValueGenerator$anyValue$1.invoke(JvmAnyValueGenerator.kt:27)
    at io.mockk.impl.instantiation.AnyValueGenerator.anyValue(AnyValueGenerator.kt:27)
    at io.mockk.impl.instantiation.JvmAnyValueGenerator.anyValue(JvmAnyValueGenerator.kt:23)
    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:263)
    at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:25)
    at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:20)
    at io.mockk.proxy.jvm.advice.BaseAdvice.handle(BaseAdvice.kt:42)
    at io.mockk.proxy.jvm.advice.jvm.JvmMockKProxyInterceptor.interceptNoSuper(JvmMockKProxyInterceptor.java:45)
    at com.my.package.database.dao.ExplanationPublicationDAO$Subclass0.doesExplanationExist(Unknown Source)
    at com.my.package.my_details.MyRepositoryTest$doesExplanationExist$1.invoke(MyRepositoryTest.kt:67)
    at com.my.package.my_details.MyRepositoryTest$doesExplanationExist$1.invoke(MyRepositoryTest.kt:29)
    at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:24)
    at io.mockk.impl.eval.RecordedBlockEvaluator$enhanceWithNPERethrow$1.invoke(RecordedBlockEvaluator.kt:74)
    at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
    at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:36)
    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 com.my.package.my_details.MyRepositoryTest.doesExplanationExist(MyRepositoryTest.kt:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:575)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:263)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Run Code Online (Sandbox Code Playgroud)

这是我的测试之一:-

@Test
fun doesExplanationExist() {

    val publicationId = UUID.randomUUID().toString()

    every { myDatabase.explanationPublicationDAO().doesExplanationExist(publicationId) } answers { MutableLiveData<Long>(0L) }

    val explanationCount = repository.doesExplanationExist(publicationId).getOrAwaitValue()

    assertEquals(0L, explanationCount)

    verify(exactly = 1) {
        myDatabase.explanationPublicationDAO().doesExplanationExist(publicationId)
    }

    confirmVerified()
}
Run Code Online (Sandbox Code Playgroud)

我的 gradle 测试条目类似于:-

def coroutines_version = '1.3.7'
def junit_version = '4.13'
def mockk_version = '1.10.0'
def archtesting_version = '2.1.0'
def unitils_version = '3.4.6'

testImplementation "junit:junit:$junit_version"
testImplementation "io.mockk:mockk:$mockk_version"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
testImplementation "androidx.arch.core:core-testing:$archtesting_version"
testImplementation "androidx.test:core:1.2.0"
testImplementation "org.unitils:unitils-core:$unitils_version"
testImplementation 'org.robolectric:robolectric:4.4'

testImplementation "org.koin:koin-test:$koin_version"

testImplementation "junit:junit:4.13"
testImplementation "androidx.test.ext:junit:1.1.1"
testImplementation project(':mock_factory')
Run Code Online (Sandbox Code Playgroud)

我的项目gradle类似于:-

buildscript {
    ext.kotlin_version = '1.3.72'
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
Run Code Online (Sandbox Code Playgroud)