0

I have trouble running some test cases, which broke after I upgraded the api to 4.1 (not sure if it is related, but the error doesn't seem to suggest so)

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)

in the given class of ShadowWebView, There is a line

private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);

The above line leads to

  Robolectric.java

which then leads to RobolectricInternals.java and executes the following method

   public static <T> T newInstanceOf(Class<T> clazz)

the method has the following source code:

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);
    }
}

the exception thrown (u see in the error log above) is because of this line

    defaultConstructor.newInstance();

i am not sure what is causing this and how to fix this only observation i made was the WebSettings.java from android used to be a non-abstract class, but now it is an abstract class, i thought this was the culprit, but then when i switched to older api such as level 12, (for which websettings.java is not declared abstract), i still have the same error

4

1 回答 1

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();

您可以在作为 Robolectric 源的一部分的 android.webkit 包中找到 TestWebSettings 类:

import android.webkit.TestWebSettings;
于 2012-10-23T23:24:29.483 回答