Robolectric单元测试报错“ReflectionHelpers.java java.lang.IllegalAccessException at UnsafeFieldAccessorImpl.java”

`macOS Catalina 10.15.6`,使用`HomeBrew`执行`brew install java`,安装了目前最新的`openjdk-14.0.1`之后,执行`bash gradlew clean build`,报告如下错误信息:

com.xxxx.plugin.face.FaceTest > executeAsync_Success FAILED
    java.lang.RuntimeException at ReflectionHelpers.java:223
        Caused by: java.lang.RuntimeException at ReflectionHelpers.java:208
            Caused by: java.lang.IllegalAccessException at UnsafeFieldAccessorImpl.java:76

目前测试发现,升级`Robolectric`版本并不能解决问题。其实对于`Android Studio`来说,完全可以指定`Android Studio`自带的`JDK`进行编译。

$ echo "export JAVA_HOME='/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home'" >> ~/.bashrc

$ source ~/.bashrc

# 由于macOS Catalina 10.15.6已经切换到zsh了,因此需要配置zsh的配置文件
$ echo "export JAVA_HOME='/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home'" >> ~/.zprofile 

$ source ~/.zprofile

关闭`SHELL`,之后重新打开新的`SHELL`,重新执行编译命令即可。

建议`Android`版本发布使用的`JDK`就是`Android Studio`自带的`JDK`,这样可以保证应用的稳定性,减少由于`JDK`差异导致的各种问题。

当前建议的版本

$ java -version
openjdk version "1.8.0_242-release"
OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
OpenJDK 64-Bit Server VM (build 25.242-b3-6222593, mixed mode)

参考链接


Robolectric单元测试报错“org.mockito.exceptions.base.MockitoException Caused by: java.lang.ClassCastException”

使用`Robolectric`进行`Android`代码测试的时候,随着测试用例的增多,可能会报告如下错误(`Windows`下常见):

> Task :biz-h5:testDebugUnitTest

com.xxxx.plugin.face.FaceTest > executeAsync_Success FAILED
    org.mockito.exceptions.base.MockitoException at FaceTest.java:71
        Caused by: java.lang.ClassCastException at FaceTest.java:71

原因为`Mockto`使用了编译缓存导致加载类的时候出现异常。解决方法是禁止`Mockto`缓存测试类的代码。

在`Android`测试项目的`src/test/java`下创建一个名为`org.mockito.configuration`的包,然后实现一个名为`MockitoConfiguration.java`的类,如下:

package org.mockito.configuration;

public class MockitoConfiguration extends DefaultMockitoConfiguration {

  @Override
  public boolean enableClassCache() {
    return false;
  }
}

这样当再次执行测试用例的时候,就已经不使用缓存了。

参考链接