Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support WebSettings.getDefaultUserAgent #2128

Closed
joeblubaugh opened this issue Nov 4, 2015 · 5 comments
Closed

Support WebSettings.getDefaultUserAgent #2128

joeblubaugh opened this issue Nov 4, 2015 · 5 comments

Comments

@joeblubaugh
Copy link
Contributor

We have some code that calls WebSettings#getDefaultUserAgent(), which is not faked in Robolectric 3.0. This leads to exceptions in the PackageManager when trying to load WebViewFactory:

android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException
    at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:161)
    at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101)
    at android.webkit.WebSettings.getDefaultUserAgent(WebSettings.java:1405)
       ....
Caused by: android.content.pm.PackageManager$NameNotFoundException
    at org.robolectric.res.builder.DefaultPackageManager.getPackageInfo(DefaultPackageManager.java:130)
    at android.webkit.WebViewFactory.$$robo$$getFactoryClass(WebViewFactory.java:133)
    at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java)
    at android.webkit.WebViewFactory.$$robo$$getProvider(WebViewFactory.java:101)
...
@jaredsburrows
Copy link
Contributor

Can you show us the code? I do not understand the NameNotFoundException?

@ernestkamara
Copy link

Just came across this same issue using PowerMock @jaredsburrows

String defaultUserAgent = WebSettings.getDefaultUserAgent(context);

and in my test...

String userAgent = "foo";
mockStatic(WebSettings.class);
when(WebSettings.getDefaultUserAgent(context)).thenReturn(userAgent);

Exception..
java.lang.IllegalStateException: Failed to transform class with name android.webkit.WebSettings. Reason: cannot find android.webkit.MustOverrideException at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:267) at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180) at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at net.zedge.say.util.DefaultClientInfoTest.testNewInstance(DefaultClientInfoTest.java:81) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873) at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773) at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:638) at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401) at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98) at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:57) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:255) at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188) at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:146) at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:139) at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.withContextClassLoader(DelegatingPowerMockRunner.java:130) at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:139) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) Caused by: javassist.CannotCompileException: cannot find android.webkit.MustOverrideException at javassist.expr.NewExpr.replace(NewExpr.java:215) at org.powermock.core.transformers.impl.MainMockTransformer$PowerMockExpressionEditor.edit(MainMockTransformer.java:418) at javassist.expr.ExprEditor.loopBody(ExprEditor.java:212) at javassist.expr.ExprEditor.doit(ExprEditor.java:91) at javassist.CtClassType.instrument(CtClassType.java:1437) at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:74) at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:252) ... 51 more Caused by: javassist.NotFoundException: android.webkit.MustOverrideException at javassist.ClassPool.get(ClassPool.java:452) at javassist.expr.NewExpr.replace(NewExpr.java:189) ... 57 more

@joeblubaugh
Copy link
Contributor Author

Argh - sorry I didn't see this email the first time around.

We have a class that's passed a Context on construction and calls:
String ua = WebSettings.getDefaultUserAgent(context); which causes the exception in the original post. Because Robolectric 3.0 doesn't include a WebViewFactory in it's classes, the PackageManager fires a name not found exception when looking it up.

We ended up modifying our test to set sdk = Build.VERSION_CODES.JELLY_BEAN to avoid triggering this behavior in the code, but more and more of our devices are on KitKat+

@jongerrish
Copy link
Contributor

Can you try this with binary resource mode and Robolectric 4.0, its likely that it should "just work" as we've done a lot of work to get the resources / manifest / package names right:-

We've revamped resources in Robolectric 4.0 to process the binary resource files + arsc table produced by aapt and the resource handling code is now much closer to that of the framework. This includes changes to parse the merged manifest using the Android platform code and an overhaul of our PackageManager support.

Mind giving this a try with 4.0 + binary resources by configuring your gradle.build as follows:-

testImplementation "org.robolectric:robolectric:4.0"

android {
  enableUnitTestBinaryResources=true
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
}

We're doing a big bug scrub and trying to be aggressive about it so apologies if this was closed in error, in which case feel free to reopen.

If this is still an issue an example project with failing test would be most helpful.

@ber4444
Copy link

ber4444 commented Dec 13, 2018

This should be reopened. Still a bug as of Robolectric 4.0.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants