我在运行一些测试用例时遇到问题,在将api升级到4.1之后中断了(不确定它是否相关,但错误似乎并不是这样)
java.lang.RuntimeException: java.lang.InstantiationException
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.newInstanceOf(RobolectricInternals.java:32)
at com.xtremelabs.robolectric.Robolectric.newInstanceOf(Robolectric.java:130)
at com.xtremelabs.robolectric.shadows.ShadowWebView.<init>(ShadowWebView.java:21)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.shadowFor(ShadowWrangler.java:163)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler$InvocationPlan.prepare(ShadowWrangler.java:311)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:81)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.view.View.<init>(View.java)
at android.view.ViewGroup.<init>(ViewGroup.java)
at android.widget.AbsoluteLayout.<init>(AbsoluteLayout.java)
at android.webkit.WebView.<init>(WebView.java)
在给定的ShadowWebView类中, 有一行
private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);
上述行导致
Robolectric.java
然后导致RobolectricInternals.java并执行以下方法
public static <T> T newInstanceOf(Class<T> clazz)
该方法具有以下源代码:
public static <T> T newInstanceOf(Class<T> clazz) {
try {
Constructor<T> defaultConstructor = clazz.getDeclaredConstructor();
defaultConstructor.setAccessible(true);
return defaultConstructor.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
抛出的异常(你在上面的错误日志中看到)是因为这行
defaultConstructor.newInstance();
我不确定是什么导致了这个以及如何解决这个问题 我所做的只是观察得到的是来自android的WebSettings.java曾经是一个非抽象类,但现在它是一个抽象类,我认为这是罪魁祸首,但是当我切换到等级12的旧api时,(对于哪个websettings.java没有声明为abstract),我仍然有相同的错误
答案 0 :(得分:0)
你是正确的,Android的WebSettings
成为API 16中的抽象类。
在API 16,Robolectric无法再通过以下方式创建WebSettings实例:
private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);
因为WebSettings是抽象的,即使通过反射也无法实例化。
因为WebSettings变得抽象,所以Robolectric必须以某种方式提供WebSettings的具体实例。所以我创建了android.webkit.TestWebSettings
类,并让Robolectric在ShadowWebView#getSettings
中返回了一个实例。
至于您的具体问题 - 您已切换到API 12但仍无法实例化WebSettings。即使您将项目更改为较低的API级别,也可能是这种情况,因为Robolectric本身仍然是针对android-16.jar构建的。如果您更改Robolectric本身以针对android-12.jar进行构建,您将获得一个WebSettings实例 - 但没有阴影实现,因为ShadowWebSettings已从当前版本的Robolectric中删除。
您问题的最简单的解决方法可能是将项目更新为API 16,然后直接在测试用例中实例化TestWebSettings对象。所以而不是:
private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);
你会写:
private WebSettings webSettings = new TestWebSettings();
您可以在android.webkit包中找到属于Robolectric源的TestWebSettings类:
import android.webkit.TestWebSettings;