Reputation: 57173
Upgrading to JUnit5, we faced a limitation:
@Test(expected = NullPointerException.class)
is no longer possible. We should use org.junit.jupiter.api.Assertions.assertThrows
these days. Normally, it takes a lambda, and it works if we set
android.compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
The problem is that we'd prefer to stay at Java 7 for the release build (it would require huge amount of testing to prove that all ancient devices that we still strive to support, work correctly with Java 8).
Is there a clean way to set sourceCompatibility
for unit test only in Android Studio?
Upvotes: 2
Views: 667
Reputation: 57173
TL;NR: The following code works for gradle tasks, but the IDE does not understand that the app classes don't use Java 8.
In Android Studio 3.0.1 with gradle plugin version 3.0.1, the following works:
tasks.all {
task ->
if (task.name.endsWith('UnitTestJavaWithJavac')) {
android.compileOptions.setSourceCompatibility(JavaVersion.VERSION_1_8)
android.compileOptions.setTargetCompatibility(JavaVersion.VERSION_1_8)
}
}
}
Now I can write
@Test
public void throwNPE() {
assertThrows(NullPointerException.class, () ->
{ int [] nullarr = null; nullarr.clone(); }
);
}
and still keep my app code at Java 7 or even Java 6.
To check how Java compiler was actually configured, I can run javap
on my app classes and on my test classes:
javap -cp build/intermediates/classes/debug -verbose com.example.Main | grep major
javap -cp build/intermediates/classes/test/debug -verbose com.example.Tests | grep major
The results are:
major version: 51
major version: 52
Unfortunately, the IDE does not understand that the app classes don't use Java 8, and warns in the following situation (see this undocumented example of Java 8 incompatibility with Java 7):
interface I {}
public class Main implements I {
<T extends I> T getI() { return (T) this };
void foo(I value) {
System.out.println("foo(I)");
}
void foo(String value) {
System.out.println("foo(String)");
}
void warn() {
foo(getI());
}
}
In spite of this warning, 'Make Proect' and 'Run Test' both pass.
Upvotes: 1