I have Android emulator tests with these basic dependencies:
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
androidTestImplementation 'androidx.test:rules:1.1.0-alpha4'
androidTestImplementation 'org.mockito:mockito-android:2.21.0'
Attempting to mock any interface results in exceptions similar to the following:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: interface com.bumptech.glide.request.RequestListener.
Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
IMPORTANT INFORMATION FOR ANDROID USERS:
The regular Byte Buddy mock makers cannot generate code on an Android VM!
To resolve this, please use the 'mockito-android' dependency for your application:
http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mockito-android%22%20g%3A%22org.mockito%22
Java : 0.9
JVM vendor name : The Android Project
JVM vendor version : 2.1.0
JVM name : Dalvik
JVM version : 0.9
JVM info : null
OS name : Linux
OS version : 3.18.91+
Underlying exception : org.mockito.exceptions.base.MockitoException:
Could not look up implicit location for storing generated classes
You can configure an explicit location by setting the system property
'org.mockito.android.target' to a folder for storing generated class files
This location must be in private scope for most API versions, for example:
MyActivity.this.getDir("target", Context.MODE_PRIVATE)
or
getInstrumentation().getTargetContext().getCacheDir().getPath()
A complete project where this is reproducible is available here: https://github.com/sjudd/glide/tree/broken_androidx_mockito_android
After checking out the project (and branch) and starting an Android emulator, you can reproduce with ./gradlew :instrumentation:connectedCheck.
I believe this is caused by Mockito relying on reflection with the android.support package here: https://github.com/mockito/mockito/blob/ee175c682aca82ac25fd2d00250f5188d6a9e954/subprojects/android/src/main/java/org/mockito/android/internal/creation/AndroidTempFileLocator.java#L26-L30
A simple solution is to just add in a check for the identical class in the androidx package. I'll send a pull request for that shortly.
I suppose it's worth noting that in the (hopefully) very short term, adding this class in the appropriate package is a simple workaround if you don't want to generalize setting the suggested property:
package android.support.test;
import android.content.Context;
public class InstrumentationRegistry {
public static Context getTargetContext() {
return androidx.test.InstrumentationRegistry.getTargetContext();
}
}
I did this in the class where I got this error and it fixed the problem for me.
static {
System.setProperty("org.mockito.android.target", ApplicationProvider.getApplicationContext().getCacheDir().getPath());
}
This should be fixed in #1583
Most helpful comment
I did this in the class where I got this error and it fixed the problem for me.
static { System.setProperty("org.mockito.android.target", ApplicationProvider.getApplicationContext().getCacheDir().getPath()); }