11

Così ho impostato il power mock in base alla guida di riferimento here. Tutto sembra funzionare perfettamente bene con una singola classe di test. Ma quando si eseguono più test JUnit, ho riscontrato il seguente errore nella seconda classe di test.Eccezione ClassCastException durante l'esecuzione di un test Robolectric con Power Mock su più file

Come si può vedere dallo stacktrace di seguito, sto provando a simulare un'istanza di otto bus. Sembrava prendere in giro correttamente la prima lezione di test, ma sulla seconda classe ho ottenuto questa eccezione per il cast di classe.

Sul stacktrace mi viene suggerito di disabilitare la cache di Objenisis ma non sono sicuro di come ottenerlo e se questa è effettivamente la causa principale mentre sto usando classloading-xstream: 1.6.2 come da collegamento Wiki Robolectric allegato sopra.

La cosa è che la mia configurazione funziona bene se eseguo una singola classe di test JUnit, ma quando provo a eseguire tutti i test in un pacchetto, solo il primo test funzionerà ei test successivi otterranno l'eccezione del cast di classe.

org.mockito.exceptions.base.MockitoException: 
    ClassCastException occurred while creating the mockito proxy : 
     class to mock : 'com.squareup.otto.Bus', loaded by classloader : '[email protected]48d' 
     created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : '[email protected]48d' 
     proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : '[email protected]' 
     instance creation by : ObjenesisInstantiator 

    You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
     at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24) 
     at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45) 
     at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     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.RunBefores.evaluate(RunBefores.java:24) 
     at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251) 
     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.junit.runners.Suite.runChild(Suite.java:128) 
     at org.junit.runners.Suite.runChild(Suite.java:27) 
     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.junit.runners.ParentRunner.run(ParentRunner.java:363) 
     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:62) 
     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
    Caused by: java.lang.ClassCastException: Cannot cast com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196 to com.squareup.otto.Bus 
     at java.lang.Class.cast(Class.java:3369) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:59) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
     at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24) 
     at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45) 
     at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) 
     at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) 
     at org.mockito.Mockito.mock(Mockito.java:1285) 
     at org.mockito.Mockito.mock(Mockito.java:1163) 
     ... 36 more 


    org.mockito.exceptions.base.MockitoException: 
    ClassCastException occurred while creating the mockito proxy : 
     class to mock : 'com.squareup.otto.Bus', loaded by classloader : '[email protected]48d' 
     created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : '[email protected]48d' 
     proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : '[email protected]' 
     instance creation by : ObjenesisInstantiator 

    You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61) 
     at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
     at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24) 
     at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45) 
     at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     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.RunBefores.evaluate(RunBefores.java:24) 
     at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251) 
     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.junit.runners.Suite.runChild(Suite.java:128) 
     at org.junit.runners.Suite.runChild(Suite.java:27) 
     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.junit.runners.ParentRunner.run(ParentRunner.java:363) 
     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:6 

risposta

2

Così ho risolto questo problema con l'aggiunta di

@PowerMockIgnore({ "*.*" }) 
@PrepareForTest({ StaticClass1.class,StaticClass2.class }) 

che renderanno Potenza finta di ignorare tutte le classi. Per il mio caso, PowerMock stava caricando in classe il Bus che nel mio codice era stato effettivamente preso in giro da Mockito. Una volta ho aggiunto le annotazioni sopra tutte le classi nella suite di test senza errori.

+0

Questo potrebbe funzionare in alcuni casi, ma ho riscontrato dei problemi nel fare ciò se si dispone di una suite di test che ha un utilizzo misto sia di PowerMockito che di Mockito. Combinare la risposta usando la classe MockitoConfiguration con @PowerMockIgnore ({"org.mockito. *"}) Sui miei test che usano PowerMockito funziona per me. – jdonmoyer

15

Suggerisco di disabilitare ClassCache di Mockito come suggerito nel messaggio di eccezione . Ecco come disabilitare Mockito ClassCache aggiungendo una classe MockitoConfiguration in Android Studio.

  1. Sotto la directory di test di unità, src/test/java, creare una directory pacchetto che è esattamente la stessa di pacchetto di progettazione Mockito, org/Mockito/configurazione.

  2. Quindi, nella directory di test completa src/test/java/org/mockito/configuration, aggiungere una nuova classe denominata MockitoConfiguration.

  3. Sovrascrive il metodo enableClassCache() come segue.

    package org.mockito.configuration; 
    
        public class MockitoConfiguration extends DefaultMockitoConfiguration { 
    
        @Override 
        public boolean enableClassCache() { 
         return false; 
        } 
    } 
    
  4. Quando si esegue il test Unità sotto src/java/test, il MockitoConfiguration devono essere caricati e cache delle classi Mockito deve essere disattivata.

Spero che sia d'aiuto.

+0

Fantastico. Grazie! – Kevin