首页 > 解决方案 > 如何使用 Robolectric 代码进行测试,即使用比 Robolectric 需要的旧番石榴版本

问题描述

我在使用 Robolectric 版本 4.51 测试使用 guava 版本 19(旧 guava 版本)的代码和库的 android 代码时遇到问题 Robolectric 测试套件需要比 19 更新的 guava 版本,否则它会输出:

java.lang.NoSuchMethodError: com.google.common.collect.ImmutableList.sortedCopyOf(Ljava/util/Comparator;Ljava/lang/Iterable;) Lcom/google/common/collect/ImmutableList;

at org.robolectric.internal.bytecode.ShadowProviders.<init>(ShadowProviders.java:25)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.robolectric.util.inject.Injector.inject(Injector.java:250)
at org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:232)
at org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:498)
at org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:224)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:208)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:202)
at org.robolectric.internal.SandboxTestRunner.<init>(SandboxTestRunner.java:78)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:103)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:98)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
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:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

如果我定义以下语句,我可以很好地编译 Robolectric 测试,但是由于 guava 版本 19 导致我的应用程序崩溃将在应用程序代码中替换为版本 27.0.1。

testImplementation 'com.google.guava:guava'
constraints {
    implementation('com.google.guava:guava:27.0.1-jre') {
        because 'Robolectric has to use this version for tests'
    }
}

此外,我尝试使用 testIplementation ('com.google.guava:guava:27.0.1-jre') 但是编译 Robolectric 测试仍然失败并出现同样的错误。

此外,我尝试执行以下操作:

testRuntimeOnly 'com.google.guava:guava:27.0.1-jre'
testImplementation 'com.google.guava:guava:27.0.1-jre'
testImplementation ("org.robolectric:robolectric:$ROBOLECTRIC_VERSION"){
    exclude group: 'com.google.guava', module: 'guava'
}

该试验也确实返回相同的错误。

我已经通过了以下建议: https ://github.com/robolectric/robolectric/issues/5147

但是他们强制执行只是为了更新番石榴,这在我的情况下不是一个选项,因为被测代码使用的是旧版本的番石榴,然后会失败......我无法更改此代码,因为它来自另一个项目团队和共享代码...

我正在使用 Gradle 6.5,我的问题如下:我怎样才能实现只有 Robolectric Testsuite 与 guava 27 一起运行,而 App 和 Testcode 仍然使用旧的 guava 版本 19?

在此先感谢您的任何建议!

标签: androidunit-testingguavarobolectric

解决方案


推荐阅读