【问题标题】:Robolectric and Android SDK 29Robolectric 和 Android SDK 29
【发布时间】:2023-03-10 12:04:01
【问题描述】:

Robolectric 何时与 Android SDK 29 兼容?将targetSdkVersioncompileSdkVersion 更改为29 是不是我升级得太早了?

当我运行我的单元测试时,我得到了这个巨大的堆栈跟踪:

java.lang.IllegalArgumentException: API level 29 is not available

    at org.robolectric.plugins.UnknownSdk.getJarPath(UnknownSdk.java:25)
    at
org.robolectric.internal.AndroidSandbox$SdkSandboxClassLoader.<init>(AndroidSandbox.java:102)
    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:239)   at
org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:221)
    at
org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:485)
    at
org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:213)
    at
org.robolectric.util.inject.Injector.resolveDependencies(Injector.java:283)
    at org.robolectric.util.inject.Injector.inject(Injector.java:237)   at
org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:221)
    at
org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:485)
    at
org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:213)
    at
org.robolectric.util.inject.Injector.getInstance(Injector.java:197)
    at org.robolectric.util.inject.Injector.access$700(Injector.java:85)
    at
org.robolectric.util.inject.Injector$ScopeBuilderProvider.create(Injector.java:551)
    at
org.robolectric.util.inject.Injector$ScopeBuilderProvider.lambda$get$0(Injector.java:534)
    at com.sun.proxy.$Proxy13.build(Unknown Source)     at
org.robolectric.internal.SandboxManager.getAndroidSandbox(SandboxManager.java:57)
    at
org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:267)
    at
org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:63)
    at
org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:215)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)    at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)  at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)     at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)   at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)     at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)    at
org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:96)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)    at
org.junit.runner.JUnitCore.run(JUnitCore.java:137)  at
org.junit.runner.JUnitCore.run(JUnitCore.java:115)  at
org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:40)
    at
java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
    at
java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)   at
java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at
java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at
java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at
java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at
java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at
java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at
java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at
org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
    at
org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:71)
    at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
    at
org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at
org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at
org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at
com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
    at
com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

【问题讨论】:

    标签: android robolectric android-10.0


    【解决方案1】:

    最新的 Robolectric 4.3 已经支持 Android Q (https://github.com/robolectric/robolectric/releases)

    【讨论】:

    • 看起来我错过了什么。当我运行单元测试时,我收到一条错误消息“IllegalArgumentException:API 级别 29 不可用”。我相应地更新了我的帖子。
    • 如何指定构建的Android Q依赖?
    • 我的 compileSdkVersion 和 targetSdkVersion 设置为 29
    • 你可以尝试使用 Q 代替吗?
    • 我真的不知道如何使用 Q 设置运行 - 我只是阅读发行说明。最好的办法是在 Robolectric GitHub 存储库上创建一张票。
    【解决方案2】:

    如果有人想知道,我的解决方案是用

    注释我的测试类
    @Config(sdk = Build.VERSION_CODES.O_MR1)
    

    【讨论】:

    • 我的解决方案是添加:@Config(sdk = [Build.VERSION_CODES.P]) using Roboelectric 4.3。
    【解决方案3】:

    app/src/test/resources 目录中创建一个robolectric.properties 文件,其中包含以下行:

    sdk=28
    

    这将强制 Robolectric 使用 API 28 而不是 29。

    【讨论】:

      【解决方案4】:

      对于Robolectric 4.3.1,我们可以使用以下替代方案:

      1. 使用 Java 9 或更高版本运行我们的测试。 (我们可以在运行测试配置中编辑JRE)

      如果我们想用 Java 8 运行我们的测试,我们可以:

      1. 使用 @Config 注释我们的测试类,以模拟较低的 SDK(如 @bencri 和 @julio-mendoza 所述)。

      像这样:

      @RunWith(AndroidJUnit4::class)
      @Config(sdk = Build.VERSION_CODES.P)
      class LoginRobolectricTest {
      //...
      }
      
      1. 或者,如@farmerbb 所述,将robolectric.properties 文件与我们希望运行的SDK 一起添加到app/src/test/resources 文件夹中,例如:

      sdk=28

      【讨论】:

      • 添加 robolectric.properties 效果最好。很简单,工作起来就像一个魅力。
      • 这对我不起作用。它似乎没有读取属性文件。知道为什么吗?现在在 Android Studio 4.0 上,它仍然失败。
      • Robolectric 使用Java 9 的目的是什么?
      • @IgorGanapolsky 在版本github.com/robolectric/robolectric/releases/tag/… 中说:在Android API 29 上运行测试现在严格要求Java9 运行时或更新版本。如果您在通过 Android Studio 在 API 29 上运行测试时看到有关不支持的 Java 版本的错误;您可以使用“运行配置”对话框中的“JRE”字段来配置更新的 Java 运行时。有关更多背景信息,请参阅developer.android.com/studio/run/rundebugconfig
      • 有趣,截至今天,Robolectric 在 API 30 上运行,但不是 31...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多