Robolectric and Android SDK 29
16,322
Solution 1
Create a robolectric.properties
file inside the app/src/test/resources
directory with the following line:
sdk=28
This will force Robolectric to use API 28 instead of 29.
Solution 2
With Robolectric 4.3.1 we can use the following alternatives:
If we like to run our test with Java 8, we can:
- Annotate our test class with @Config in order to emulate a lower SDK (as mentioned by @bencri and @julio-mendoza).
Like this:
@RunWith(AndroidJUnit4::class)
@Config(sdk = Build.VERSION_CODES.P)
class LoginRobolectricTest {
//...
}
- Or, as mentioned by @farmerbb, add the
robolectric.properties
file inside theapp/src/test/resources
folder with the SDK we like to run, by example:
sdk=28
Solution 3
If anyone is wondering, the solution for me was to annotate my test classes with
@Config(sdk = Build.VERSION_CODES.O_MR1)
Solution 4
Latest Robolectric 4.3 already supports Android Q (https://github.com/robolectric/robolectric/releases)
Related videos on Youtube
Author by
Bencri
Updated on June 20, 2022Comments
-
Bencri about 2 years
When will Robolectric be compatible with Android SDK 29? Did I upgraded too early by changing
targetSdkVersion
andcompileSdkVersion
to 29?When I run my unit tests I get this huge stacktrace:
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)
-
Bencri about 5 yearsLook like I'm missing something then. When I run my unit tests I get an error message "IllegalArgumentException: API level 29 is not available". I updated my post accordingly.
-
Eugen Martynov about 5 yearsHow do you specify Android Q dependency of the build?
-
Bencri about 5 yearsMy compileSdkVersion and targetSdkVersion are set to 29
-
Eugen Martynov almost 5 yearsCan you try using Q instead?
-
Eugen Martynov almost 5 yearsI don't really know how to set up the run with Q - I just read release notes. The best would be to create a ticket on the Robolectric GitHub repository.
-
Julio Mendoza almost 5 yearsThe solution for me was to add:
@Config(sdk = [Build.VERSION_CODES.P])
using Roboelectric 4.3. -
portfoliobuilder over 4 yearsAdding robolectric.properties worked best. Was easy and worked like a charm.
-
Vitor Hugo Schwaab over 4 yearsThe issue really is, as the link you sent says: Running tests on Android API 29 now strictly requires a Java9 runtime or newer. This can be easily fixed in dev environment. But people might strugle changing CI/CD environments.
-
Eugen Martynov over 4 years@VitorHugoSchwaab if you use Docker on your CI then it is much easier than dev machine changes
-
Randy about 4 yearsThis doesn't work for me. It doesn't seem to be reading the properties file. Any idea why? On Android Studio 4.0 now and it is still failing.
-
IgorGanapolsky almost 3 yearsWhat is the purpose of using
Java 9
with Robolectric? -
JuanMoreno almost 3 years@IgorGanapolsky in the release github.com/robolectric/robolectric/releases/tag/… says this: Running tests on Android API 29 now strictly requires a Java9 runtime or newer. If you are seeing errors about unsupported Java version when running tests on API 29 via Android Studio; you can use the 'JRE' field in the Run Configuration dialog to configure a newer Java runtime. See developer.android.com/studio/run/rundebugconfig for more background.
-
IgorGanapolsky almost 3 yearsInteresting, as of today Robolectric runs on API
30
, but not31
... -
JuanMoreno almost 3 years@IgorGanapolsky, yeah, also if you see the Robolectric's CI run against Java 11.0.8 github.com/robolectric/robolectric/blob/…