Android Webview Chromium单元测试出现java.lang.NoSuchMethodError如何解决
问题复现
在使用Robolectric 4.3.1版本和Mockito 2.18.3版本编写单元测试时,出现NoSuchMethodError报错,异常信息如下:
java.lang.NoSuchMethodError: 'void com.android.webview.chromium.WebViewChromium.<init>(com.android.webview.chromium.WebViewChromiumFactoryProvider, android.webkit.WebView, android.webkit.WebView$PrivateAccess, boolean)'
相关实现代码如下:
mWebView = Mockito.spy( new WebviewChromium( mockWebViewChromiumProvider, webView, webView.new PrivateAccess(), false));
已在BUILD.gn中引入//android_webview/glue:glue_java依赖,代码可正常编译,但运行时出现类调用错误。
解决方案
- 调整BUILD.gn依赖优先级
编译正常说明编译期依赖正确,运行时错误是类加载顺序问题。将//android_webview/glue:glue_java放在junit_binary目标的deps列表最前方,优先级高于Robolectric、系统android.jar等相关依赖,确保运行时优先加载本地编译的WebViewChromium类。 - 禁用Robolectric默认ShadowWebView实现
Robolectric 4.x版本默认自带ShadowWebView实现,会替换系统原生WebView相关类,导致构造方法不匹配。在测试类添加@Config(shadows = {}, exclude = ShadowWebView.class)注解,或在robolectric.properties配置文件中添加shadowWebView=false,关闭自带的WebView影子类逻辑。 - 调整Mockito spy逻辑
如果构造方法匹配问题是Mockito代理导致的,可改为先创建WebViewChromium实例再调用spy方法,或替换为mock WebView对外暴露的接口层,避免直接spy内部实现类WebViewChromium。 - 强制指定运行时classpath
在BUILD.gn的junit_binary目标中添加classpath_flags = [ "-cp", rebase_path("//out/Release/obj/android_webview/glue/glue_java.jar") ]配置(路径根据实际编译输出调整),显式将glue_java的jar包加到classpath最前端,覆盖冲突的类定义。
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

