11

リファレンスガイドhereに基づいて電源モックを設定します。 1つのテストクラスで完全に正常に動作するようです。しかし、複数のJUnitテストを実行すると、2番目のテストクラスで次のエラーが発生します。複数のファイルでPower Mockを使用したRobolectricテストを実行しているときのClassCastException例外

以下のスタックトレースからわかるように、私はotto Busインスタンスをモックしようとしています。最初のテストクラスでは正しく模倣したようですが、2番目のクラスではこのクラスキャスト例外が発生しています。

Obtenisisキャッシュを無効にする提案がありますが、これを達成する方法がわかりません。実際にはclassloading-xstreamを使用しているため、根本的な原因です。1.6.2 Robolectric Wikiリンクが添付されています上記。

1つのJUnitテストクラスを実行するとセットアップがうまく動作しますが、パッケージ内のすべてのテストを実行しようとすると、最初のテストだけが実行され、その後のテストではクラスキャストの例外が発生します。

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 

答えて

2

だから私はパワーがモッククラスをすべて無視するということ

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

を追加することで、この問題を解決しました。私の場合、PowerMockは私のコードで実際にMockito.Onceによって模擬されたBusをクラスローディングしていましたが、上記の注釈を追加しましたが、テストスイート内のすべてのクラスはエラーなく動作しました。

+0

これはいくつかのケースではうまくいくかもしれませんが、PowerMockitoとMockitoの両方を混在させたテストスイートがある場合、これを行う際に問題が見つかりました。 PowerMockitoを使用するテストでは、MockitoConfigurationクラスを使用した回答を@PowerMockIgnore({"org.mockito。*"})と組み合わせて使用​​します。 – jdonmoyer

15

例外メッセージ で提案されているように、MockitoのClassCacheを無効にすることをお勧めします。 AndroidスタジオでMockitoConfigurationクラスを追加してMockito ClassCacheを無効にする方法は次のとおりです。あなたのユニットテストのディレクトリはsrc /テスト/ javaの下で

  1. 、正確Mockito構成パッケージ、ORG/mockito /構成と同じであるパッケージディレクトリを作成します。

  2. したがって、完全なテストディレクトリsrc/test/java/org/mockito/configurationの下に、MockitoConfigurationという名前の新しいクラスを追加します。

  3. enableClassCache()メソッドを次のように上書きします。

    package org.mockito.configuration; 
    
        public class MockitoConfiguration extends DefaultMockitoConfiguration { 
    
        @Override 
        public boolean enableClassCache() { 
         return false; 
        } 
    } 
    
  4. あなたはのsrc/javaの/テスト中のあなたのユニットテストを実行すると、あなたのMockitoConfigurationをロードする必要があるとMockitoクラスのキャッシュを無効にする必要があります。

希望します。

+0

恐ろしい。ありがとう! – Kevin

関連する問題