2013-04-30 104 views
4

我正在嘗試將靜態方法剔除,以便我可以單元測試REST Api接口。在Android上使用PowerMockito嘲笑靜態方法

我使用...

  • PowerMockito 1.5(使靜態的嘲諷)
  • Roboelectric 1.2(存根出了android的其餘部分)
  • JUnit的4.10

運行以下代碼給我後續錯誤

任何想法o ñ什麼能解決這個問題?

@RunWith(RobolectricTestRunner.class) 
    @PrepareForTest({Api.class}) 
    public class ApiTest extends TestCase { 

     @Rule 
     public PowerMockRule rule = new PowerMockRule(); 
     ... 
     @Test 
     public void testGet() throws Exception { 
      Api.Response fakeResponse = PowerMockito.mock(Api.Response.class); 
      PowerMockito.when(fakeResponse.getResult()).thenReturn(responseObj); 
      mockStatic(Api.class); 
      PowerMockito.when(Api.execute(any(HttpRequestBase.class))).thenReturn(fakeResponse); 
      Api.get("/v1/contacts/"); 
     } 
    } 

但是之前我們所說的「Api.get」上的靜態權存根引發以下錯誤......

java.lang.RuntimeException: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for org.powermock.classloading.DeepCloner 
    at org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:68) 
    at org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:34) 
    at org.powermock.classloading.ClassloaderExecutor.createDeepCloner(ClassloaderExecutor.java:106) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:88) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) 
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49) 
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for org.powermock.classloading.DeepCloner 
    at javassist.Loader.findClass(Loader.java:360) 
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.findClass(RobolectricClassLoader.java:83) 
    at javassist.Loader.loadClass(Loader.java:312) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.loadClass(RobolectricClassLoader.java:59) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247) 
    at org.powermock.api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:66) 
    ... 24 more 
Caused by: com.xtremelabs.robolectric.bytecode.IgnorableClassNotFoundException: msg because of javassist.NotFoundException: org.powermock.classloading.DeepCloner 
    at com.xtremelabs.robolectric.bytecode.AndroidTranslator.onLoad(AndroidTranslator.java:92) 
    at javassist.Loader.findClass(Loader.java:341) 
    ... 31 more 

回答

1

具有靜態嘲笑你必須使用PowerMockRunner,否則不起作用。請參閱文檔。

如果可能的話,我總是避免靜態嘲笑,因爲類加載併發症。如果你想分享測試過的代碼,也許我可以提出一些解決方法。通常我在類中創建一個非靜態方法,它使用靜態方法,並且我在這個非靜態方法中調用靜態方法。然後,我只是讓被測試的類的一個間諜,我嘲笑這種方法。這樣我不需要PowerMock。

+0

我剛纔遇到了這個問題,這是我最終可能發現的這個錯誤的唯一參考 - 我一直認爲我一定在做錯事。這是在文檔中的哪個位置說明的?我可以證實這種情況 - 在將我的測試縮減爲最基本要素之後,靜態嘲笑在從跑步者切換到規則時停止工作。這太糟糕了,因爲這意味着當你不得不在不同的跑步者下跑時,你會失去很多PowerMock的價值。 – 2014-08-21 14:37:16

+0

@Tom Tresansky:你可以嘗試基於代理的powermocking,它可以讓你使用不同的跑步者。請參閱https://code.google.com/p/powermock/wiki/PowerMockAgent – 2014-08-21 21:20:55

+0

我認爲這是我們已經試圖做的事情?我問了一個新問題: http://stackoverflow.com/questions/25850673/is-it-possible-to-mock-a-static-method-on-a-final-class-using-a- powermockrule-in來完全澄清這一點。 – 2014-09-15 14:53:53