問題描述
我之所以問,是因為我正在嘗試使用一個不允許您模擬靜態方法的模擬框架 (Mockito).調查它,我發現很多博客文章說你應該盡可能少地使用靜態方法,但我很難理解為什么.特別是為什么不修改全局狀態并且基本上是輔助方法的方法.例如,我有一個名為 ApiCaller
的類,它有幾個靜態方法.靜態方法的目的之一是執行 HTTP 調用,處理我們的服務器可能返回的任何自定義問題(例如用戶未登錄)并返回響應.為了簡化,類似:
I'm asking because I'm trying to use a mocking framework (Mockito) which does not allow you to mock static methods. Looking into it I've found quite a few blog posts saying that you should have as few static methods as possible, but I'm having difficulty wrapping my head around why. Specifically why methods that don't modify the global state and are basically helper methods. For instance I have a class called ApiCaller
that has several static methods. One of the static method's purpose is to execute an HTTP call, deal with any custom issues our server might have returned (ex. user not logged in) and return the response. To simplify, something like:
public class ApiCaller {
...
public static String makeHttpCall(Url url) {
// Performs logic to retrieve response and deal with custom server errors
...
return response;
}
}
要使用它,我只需調用 ApiCaller.makeHttpCall(url)
現在我可以輕松地將其設為非靜態方法,例如:
To use this all I have to do is call ApiCaller.makeHttpCall(url)
Now I could easily make this a non static method like:
public class ApiCaller {
...
public String makeHttpCall(Url url) {
// Performs logic to retrieve response and deal with custom server errors
...
return response;
}
}
然后使用此方法調用 new ApiCaller().makeHttpCall()
但這似乎是額外的開銷.誰能解釋為什么這很糟糕,以及是否有更好的解決方案使方法成為非靜態方法(除了刪除關鍵字之外),以便我可以使用模擬框架刪除這些方法?
and then to use this method call new ApiCaller().makeHttpCall()
but this just seems like extra overhead. Can anyone explain why this is bad and if there is a better solution to making the methods non static (other than just removing the keyword) so that I can stub out these methods using the mocking framework?
謝謝!
推薦答案
靜態方法的問題是當它們與您嘗試測試的系統無關時,它們很難偽造.想象一下這段代碼:
The problem with static methods is they're very hard to fake when they're not relevant to the system you're trying to test. Imagine this code:
public void systemUnderTest() {
Log.connectToDatabaseForAuditing();
doLogicYouWantToTest();
}
connectToDatabaseForAuditing()
方法是靜態的.您不在乎此方法對您要編寫的測試有什么作用.但是,現在要測試此代碼,您需要一個可用的數據庫.
The connectToDatabaseForAuditing()
method is static. You don't care what this method does for the test you want to write. But, to test this code now you need an available database.
如果它不是靜態的,代碼將如下所示:
If it were not static the code would look like this:
private Logger log; //instantiate in a setter AKA dependency injection/inversion of control
public void systemUnderTest() {
log.connectToDatabaseForAuditing();
doLogicYouWantToTest();
}
如果現在沒有數據庫,您的測試將是微不足道的:
And your test would be trivial to write without a database now:
@Before
public void setUp() {
YourClass yourClass = new YourClass();
yourClass.setLog(new NoOpLogger());
}
//.. your tests
想象一下當方法是靜態的時嘗試這樣做.除了修改記錄器以擁有一個名為 inTestMode
的靜態變量,您在 setUp()
中將其設置為 true 以確保它不會'不連接到數據庫.
Imagine trying to do that when the method is static. I can't really think of a way except for modifying the logger to have a static variable called inTestMode
that you set to true in the setUp()
to make sure it doesn't connect to a database.
這篇關于為什么在 Java 中使用靜態輔助方法不好?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!