Hi there sd2011,
You are correct that WebSettings became an abstract class in API 16.
At API 16, Robolectric could no longer create an instance of WebSettings via:
private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);
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.TestWebSettings class, and made Robolectric return an instance of that in ShadowWebView#getSettings.
There's some things I don't like about this approach:
1) TestWebSettings resides in the android.webkit package, and not in any Robolectric package. That's because Google, in their infinite wisdom, made the constructors for WebSettings package-protected, and so any subclass must reside in the same package as WebSettings.
2) The ShadowWebSettings class went away entirely, with all of its code moving into TestWebSettings. I got rid of ShadowWebSettings mainly because I didn't want two copy/paste implementations of the same code lying around in Robolectric - it would have been a maintenance nightmare waiting to happen. (There may also have been either a compile-time or runtime problem with keeping a shadow for an abstract class, but my memory is hazy).
As to the problem you reported in your StackOverflow post - 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:
private WebSettings webSettings = Robolectric.newInstanceOf(WebSettings.class);
you would write:
private WebSettings webSettings = new TestWebSettings();
Robolectric ideally should have some type of mechanism that allows it to serve up one of several alternate implementations of WebSettings based upon Android API level. What I'm not yet convinced of is whether the resulting source code can build against any Android API jar without modification, or whether we would need to build several jar files for Robolectric, one targeting each version of the API.
Best regards,
Michael Portuesi