2012-03-06 1743 views
43

我在我的項目中有幾個靜態util方法,其中一些只是傳遞或拋出異常。有很多關於如何模擬一個返回類型不是void的靜態方法的例子。但我怎麼能嘲笑一個靜態方法返回到「doNothing()」?如何模擬一個返回void和PowerMock的靜態方法?

非空版本使用代碼的這些行:

@PrepareForTest(StaticResource.class) 

...

PowerMockito.mockStatic(StaticResource.class); 

...

Mockito.when(StaticResource.getResource("string")).thenReturn("string"); 

但是如果應用到StaticResources返回void,編譯會抱怨when(T)不適用於void ...

任何想法?

解決方法可能是讓所有靜態方法都成功返回一些Boolean,但我不喜歡解決方法。

回答

25

您可以像使用Mockito一樣在實際情況下執行此操作。例如,您可以鏈存根,下面一行將在第一次調用什麼都不做,那麼第二和未來getResources調用將拋出異常:

// the stub of the static method 
doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

// the use of the mocked static code 
StaticResource.getResource("string"); // do nothing 
StaticResource.getResource("string"); // throw Exception 

感謝馬特拉克曼的備註,請注意,如果默認答案在模擬創建時不會改變,模擬默認不會做任何事情。因此編寫下面的代碼相當於不寫它。

doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

雖然這樣說,但它可以爲同事將讀取的測試,你不指望什麼了這個特殊的代碼有趣。當然這可以根據測試的可理解性的方式進行調整。


順便說一句,在我的愚見,你應該避免嘲笑靜態代碼,如果你的各具特色的新代碼。在Mockito,我們認爲這通常暗示了糟糕的設計,這可能會導致代碼維護性差。儘管現有的遺留代碼是另一回事。

一般來說,如果你需要模擬私有或靜態方法,那麼這個方法做得太多了,應該在將被注入被測對象的對象中進行外化。

希望有所幫助。

問候

+1

不幸不會當()只接受可變和StaticResource的是一種類型的工作。 ('StaticResource不能解析爲一個變量') – Pete 2012-03-06 14:43:52

+0

哦對對不起,你是正確的我的代碼是錯誤的,我要習慣於非靜態模擬。無論如何,我更新了我的支持以反映正確的語法。 – Brice 2012-03-06 16:14:19

+0

謝謝!因此,有沒有依賴的靜態幫助器方法是一個壞主意? 當然,我可以只注入和反對這個工作,但是覺得將沒有依賴關係的工作者放在靜態對象中來表示他們的獨立性是有意義的。 – Pete 2012-03-07 06:35:35

55

您可以存根這樣的靜態無效的方法:

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString()); 

雖然我不知道你爲什麼會打擾,因爲當你調用mockStatic(靜態資源。類)在StaticResource的所有靜態方法都默認存根

更加有用,您可以捕捉)這樣傳遞給StaticResource.getResource(價值:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 
PowerMockito.doNothing().when(
       StaticResource.class, "getResource", captor.capture()); 

然後你可以評估的字符串傳遞給StaticResource.getResource這樣的:

String resourceName = captor.getValue(); 
+0

能夠做到這一點非常酷,因爲它可以讓你像嘲諷Thread.sleep(long millis)那樣做一些事情,以便不同的時間/更少的時間/沒有時間的睡眠! – fragorl 2014-09-30 03:40:16

+0

有沒有辦法避免使用字符串的方法 - 作爲「getResource」在你的例子? – 2016-03-01 07:59:03

8

簡單來說, 試想一下,如果你想在下面一行模擬:

StaticClass.method(); 

那麼你就寫下面的代碼行,以模擬:

PowerMockito.mockStatic(StaticClass.class); 
PowerMockito.doNothing().when(StaticClass.class); 
StaticClass.method(); 
1

嘲笑,對於例如返回void一個靜態方法Fileutils.forceMKdir(File file),

樣品的編號:

File file =PowerMockito.mock(File.class); 
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file); 
相關問題