Robolectric no utiliza ShadowWebView como la superclase de una clase que extiende WebView. MustOverrideException en su lugar

Estoy tratando de obtener Robolectric 2.1 trabajando con mi proyecto y obtener una MustOverrideException cuando mi subclase de WebView intenta llamar a setDatabasePath en su WebSettings. Tengo una clase de aplicación personalizada que intenta crear una instancia de una subclase de WebView en onCreate. Como parte de ese constructor de WebView, intenta establecer la ruta de la base de datos.

Hubiera pensado que desde que getSettings se estaba llamando desde WebView, que la llamada realmente habría afectado a ShadowWebView, que se supone devolver un objeto TestWebSettings que no arroja esas excepciones. En su lugar, parece estar llamando a la normal WebSettings.getSettings y devolver algo que no tiene los métodos implementados. He intentado usar @Config (shadows = ShadowWebView.class) para mi prueba, pero sin cambios. He intentado crear una sombra personalizada de mi vista web especializada y aplicarla a la prueba, pero todavía llama a la clase personalizada normal. Esta es la excepción que veo cuando intento ejecutar mis pruebas:

java.lang.RuntimeException: android.webkit.MustOverrideException: abstract function called: must be overriden! at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:231) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) at com.sun.proxy.$Proxy2.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355) at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:680) Caused by: android.webkit.MustOverrideException: abstract function called: must be overriden! at android.webkit.WebSettings.setDatabasePath(WebSettings.java:932) at com.example.android.jsbridge.ExWebView.init(ExWebView.java:237) at com.example.android.jsbridge.ExWebView.<init>(ExWebView.java:187) at com.example.android.jsbridge.ExWebView.getInstance(ExWebView.java:192) at com.example.android.ExApplication.onCreate(ExApplication.java:88) at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:146) at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:387) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:227) 

Me gustó la respuesta de Jearil, pero no tener que esperar a una nueva versión es aún mejor. He extendido ShadowWebView y TestWebSettings para agregar el método que no se implementó.

ExtendedShadowWebView.java

 @Implements(value = WebView.class, inheritImplementationMethods = true) public class ExtendedShadowWebView extends ShadowWebView{ private WebSettings webSettings = new ExtendedTestWebSettings(); @Implementation public WebSettings getSettings() { return webSettings; } } 

ExtendedTestWebSettings.java

 public class ExtendedTestWebSettings extends TestWebSettings { @Implementation public void setDefaultFontSize(int fontSize) { // This was the method I needed, replace with your setDatabasePath } } 

MyActivityTest.java

 @RunWith(RobolectricTestRunner.class) @Config(manifest = TestUtility.ANDROID_MANIFEST_XML,shadows=ExtendedShadowWebView.class) public class MyActivityTest { 

Esto terminó siendo un error en robolectric sí mismo. Utilizan una clase TestWebSettings que proporciona implementación para la clase WebSettings de Android y les faltaba una implementación para setDatabasePath. He enviado un parche https://github.com/robolectric/robolectric/commit/7eff08c896ccce4a01c887b89db64bcb808158e4 que fue aceptado y entrará en una versión futura. También arreglé un error similar con setRenderPriority.

  • Android Load Cache Only no funciona. Mostrar WebView fuera de línea
  • No se puede eliminar la imagen en div contenteditable en Android
  • Justificar texto de android dentro de un listview sin usar un WebView
  • Android WebView transparente en la parte superior de VideoView
  • ¿Es posible obtener datos de formularios HTML en android mientras se usa webView?
  • Android: Abrir un ContextMenu desde onLongPress en WebView personalizado
  • ¿Hay una mejor vista web para Android
  • ¿WebView saveState () preserva variables / entorno de JavaScript?
  • WebView saltar para anclar utilizando loadDataWithBaseUrl
  • ¿Por qué jQuery Mobile 1.1-rc1 utiliza un .gif para el icono de carga (de nuevo)?
  • Android PhoneGap obtener guiñada, tono, rollo, relativo a las coordenadas de tierra
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.