問題描述
誰能總結一下,在 Mockito 之上添加 PowerMock 的具體功能是什么?
Can anyone please summarize, what exactly features gives you adding PowerMock on top of the Mockito?
到目前為止,我已經找到了這些:
So far I've found these:
- 模擬靜態、最終和私有方法
- 移除靜態初始化器
- 允許在沒有依賴注入的情況下進行模擬 - 我不清楚這一點.你能詳細說明一下嗎?
它是否添加了其他內容?你能概括幾行嗎?
Does it add anything else? Can you please sum up in several lines?
在使用 PowerMock 時我是否需要犧牲一些東西?
And do I need to sacrifice something when using PowerMock?
推薦答案
我不知道其他好處,但我想解決您的 2 個子問題(這對于評論來說太長了):
I don't know of other benefits offhand, but I want to address 2 of your sub-questions (and this is way too long for a comment):
允許在沒有依賴注入的情況下進行模擬 - 我不清楚這一點.能詳細點嗎?
allow mocking without dependency injection - this one isn't clear to me. Can you elaborate?
我認為這來自 Motivation wiki 頁面,他們在其中描述了一種將代碼重構為不調用靜態方法使其可測試.對于我認為他們正在處理的具體示例,假設您有這段代碼,并且您想測試模擬靜態方法行為的方法,而不使用 powermock:
I think this came from the Motivation wiki page where they describe a way of refactoring code to not invoke static methods to make it testable. For a concrete example of what I think they're getting at, let's say you have this code and you want to test the method mocking the behaviour of the static method, without using powermock:
public class MyClass {
public void doGetString() {
...
OtherClass.getString(); //It's complex and scary and needs mocking!
...
}
}
一種解決方案是將靜態調用拉到它自己的對象中,然后注入一個可以在測試時模擬的對象.例如,在不使用其他框架的情況下,這可能如下所示:
One solution, would be to pull the static invocation into its own object, then inject an object that can be mocked come test time. For example, without using other frameworks, this could look like:
public class MyClass {
public static class StringGetter {
public getString() {
return OtherClass.getString();
}
}
private final StringGetter getter;
//Existing Constructor
public MyClass() {
this(new StringGetter());
}
//DI Constructor
MyClass(StringGetter getter) {
this.getter = getter;
}
public void doGetString() {
...
getter.getString();
...
}
}
我已經將我的方法的行為與靜態調用的行為分開,并且可以在測試時使用 DI 構造函數輕松地注入模擬.當然,使用 powermock 我可以在適當的位置模擬靜態方法,然后使用它運行.
I've seperated the behaviour of my method from the behaviour of the static invocation, and can use the DI constructor to inject mocks easily at test time. Of course with powermock I could just mock the static method in place, and run with it.
在使用 PowerMock 時我是否需要犧牲一些東西?
And do I need to sacrifice something when using PowerMock?
物理上不,但我會說哲學上是:).以下是我的觀點,我試圖給出很好的理由,但當然它們是觀點,所以請持保留態度:
Physically no, but I'd say philosophically yes :). The below are my opinions, and I try to give good reasons behind them, but of course they are opinions so take them with a grain of salt:
PowerMock 發生的潛在可怕的事情是,為了完成模擬私有和靜態方法的壯舉,它們使用自定義類加載器(在生產運行時不應存在)并更改字節碼你的課.可以說,在大多數情況下,這對于絕大多數類來說都無關緊要,但如果你考慮一下,如果字節碼發生了變化,并且某些副作用不再存在,那么你實際上是在根據你的現有的類.是的,這是一個非常學術的論點.
The potentially scary thing that is happening with PowerMock is that in order to accomplish the feats of mocking private and static methods, they are using a custom class loader (which shouldn't be present at runtime in production) and changing the bytecode of your classes. Arguably, this should not matter with the vast majority of classes most of the time, but if you think about it, if the bytecode has changed, and certain side effects are no longer present, you're effectively testing different Classes albiet based upon your existing Classes. Yes this is a very academic argument.
通過不使用 PowerMock 的良好綜合集成和更高級別的測試,您可以在一定程度上緩解第一個論點.通過這種方式,即使您的單元測試使用的是 PowerMock,您也可以對對象的行為更有信心.
You can somewhat mitigate this first argument by having good comprehensive integration and higher level tests that don't use PowerMock. In this way you can be more confident in the behaviours of your objects even if your unit tests are using PowerMock.
我反對 PowerMock 的另一個論點是,它幾乎太容易成為拐杖.我同意 PowerMock 可以幫助測試使用遺留代碼和您無法控制的其他代碼的代碼.但是我認為,當您可以控制需要模擬的類時,您應該避免使用它.如果您編寫一個帶有私有方法或靜態方法的類,您需要顯式地模擬以測試其他方法,我的直覺會說這個方法可能做得太多,應該重構和分解.PowerMock 已經在項目中可用,您可能會想模擬它并繼續前進,這將減輕應該鼓勵您重構相同的痛苦.是的,有時由于各種技術和非技術限制,這是不可能的,但解決痛點而不是避免它們是件好事:)
The other argument I have against PowerMock, is that it could almost too easily become a crutch. I agree that PowerMock can help with testing code that uses legacy code and other code that you do not have control over. However I would argue that when you have control over the classes that you need to mock, you should avoid its use. If you write a class with a private method or static method that you need to explicitly mock in order to test other methods, my gut instinct would say that this method may be doing too much and should be refactored and broken up. Having PowerMock already available in a project, you may be tempted to just mock it and move on, which would mitigate the pain that should encourage you to refactor the same. Yes there are sometimes due to various technical and non-technical constraints this is not possible, but it's good to solve pain points instead of avoid them :)
這篇關于PowerMock + Mockito VS Mockito 單獨的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!