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
You are correct that Android’s
WebSettingsbecame an abstract class in API 16.At API 16, Robolectric could no longer create an instance of WebSettings via:
because WebSettings is abstract and cannot be instantiated even by reflection.
Because WebSettings became abstract, Robolectric has to somehow offer a concrete instantiation of WebSettings. So I created the
android.webkit.TestWebSettingsclass, and made Robolectric return an instance of that inShadowWebView#getSettings.As to your specific problem – that you switched to API 12 but still cannot instantiate WebSettings. This is likely to be the case even if you change your project to a lower API level, because Robolectric itself is still built against the android-16.jar. If you change Robolectric itself to build against android-12.jar, you will get an instance of WebSettings – but without a shadow implementation because ShadowWebSettings has been removed from the current version of Robolectric.
The easiest workaround for your problem would probably be to update your project to API 16, and then instantiate a TestWebSettings object directly in your test case. So instead of:
you would write:
You can find the TestWebSettings class in the android.webkit package that is part of the Robolectric source: