java android powermock robolectric

java - Usando PowerMock y Robolectric-IncompatibleClassChangeError



android (1)

Encontré una forma de usar PowerMock junto con Robolectric.

Además de los tarros PowerMock estándar, también se necesita la Regla Junit de PowerMock. Se describe here cómo agarrarlo. Utilicé la versión de xstream clases xstream , porque la objenesis uno tiene muchos errores. Esto funciona con PowerMock 1.5.5 y Robolectric 2.3, no puedo hablar de las versiones anteriores. También tenga en cuenta que el agente Java no debe incluirse, ya que, según mi experiencia, causa problemas.

Entonces, si está utilizando maven, estas dependencias deben ser declaradas:

<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4-rule</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-classloading-xstream</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency>

Entonces tienes que configurar tu clase de prueba así:

@RunWith(RobolectricTestRunner.class) @PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" }) @PrepareForTest(Static.class) public class MyTest { @Rule public PowerMockRule rule = new PowerMockRule(); private MyActivity activity; @Before public void setup() { activity = Robolectric.buildActivity(MyActivity.class).create().get(); } @Test public void test() throws Exception { PowerMockito.mockStatic(Static.class); Mockito.when(Static.getCurrentTime()).thenReturn(1); Assert.assertEquals(1, activity.getId()); } }

Estoy tratando de usar PowerMockito para simular algunos métodos estáticos en las pruebas de Android Robolectric. Estoy usando JUnit 4.8.2, Robolectric 2.2, Mockito 1.9.5 y PowerMock 1.9.5 como se indica here . Como tengo que usar el RoboElectricTestRunner , estoy intentando usar la PowerMockRule para arrancar PowerMock. Sin embargo, estoy obteniendo un java.lang.IncompatibleClassChangeError desafortunado cuando se ejecuta la prueba con PowerMock.

java.lang.reflect.InvocationTargetException
en sun.reflect.NativeMethodAccessorImpl.invoke0 (Método nativo)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke.reflect .MethodAccessorImpl.java:25) en java.lang.niv.nflect.
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent (InstrumentationImpl.java:323) at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain (InstrumentationImpl.java:348)

Causado por: java.lang.IncompatibleClassChangeError: Implementando la clase en java.lang.ClassLoader.defineClass1 (Método nativo)
at java.lang.ClassLoader.defineClassCond (ClassLoader.java:637) at java.lang.ClassLoader.defineClass (ClassLoader.java:621) at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:141)

Si pongo org.ow2.asm después de las bibliotecas org.powermock obtengo:

java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode tiene una interfaz org.objectweb.asm.ClassVisitor como super clase en java.lang.ClassLoader.defineClass1 (Native Method) en java.lang.ClassLoader.defineClass .java: 637) en java.lang.ClassLoader.defineClass (ClassLoader.java:621) en java.security.SecureClassLoader.defineClass (SecureClassLoader.java:141) en java.net.URLClassLoader.defineClass (URLClassLoader. en java.net.URLClassLoader.access $ 000 (URLClassLoader.java:58) en java.net.URLClassLoader $ 1.run (URLClassLoader.java:197) en java.security.AccessController.doPrivileged (Método nativo)

en cada prueba de unidad.

De acuerdo con la dependencia de Maven: tree Robolectric y PowerMock no comparten ninguna dependencia. Pero aparentemente, org.powermock: powermock-module-javaagent empaqueta algunas clases de org / objectweb / asm , y Robolectric confía en org.ow2.asm: asm: jar: 4.1 causando un conflicto.

@RunWith(RobolectricTestRunner.class) @PrepareForTest(Helper.class) @PowerMockIgnore({"com.sun.jmx.*", "javax.management.*"}) public class HelpFragTest { @Rule public PowerMockRule rule = new PowerMockRule(); static { PowerMockAgent.initializeIfNeeded(); } FragmentActivity fragmentActivity; FragmentManager fragmentManager; ActionBarManager actionBarManager; @Before public void setup(){ actionBarManager = mock(ActionBarManager.class); LowesApplication.instance().setActionBarManager(actionBarManager); fragmentActivity = Robolectric.buildActivity(FragmentActivity.class).create().start().resume().get(); fragmentManager = fragmentActivity.getSupportFragmentManager(); } @Test public void testShow(){ mockStatic(Helper.class); HelpFrag helpFrag = HelpFrag.newInstance(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(helpFrag, null); fragmentTransaction.commit(); assertTrue(helpFrag.isVisible()); } }