問題描述
誰能總結(jié)一下,在 Mockito 之上添加 PowerMock 的具體功能是什么?
Can anyone please summarize, what exactly features gives you adding PowerMock on top of the Mockito?
到目前為止,我已經(jīng)找到了這些:
So far I've found these:
- 模擬靜態(tài)、最終和私有方法
- 移除靜態(tài)初始化器
- 允許在沒有依賴注入的情況下進(jìn)行模擬 - 我不清楚這一點(diǎn).你能詳細(xì)說明一下嗎?
它是否添加了其他內(nèi)容?你能概括幾行嗎?
Does it add anything else? Can you please sum up in several lines?
在使用 PowerMock 時(shí)我是否需要犧牲一些東西?
And do I need to sacrifice something when using PowerMock?
推薦答案
我不知道其他好處,但我想解決您的 2 個(gè)子問題(這對(duì)于評(píng)論來說太長了):
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):
允許在沒有依賴注入的情況下進(jìn)行模擬 - 我不清楚這一點(diǎn).能詳細(xì)點(diǎn)嗎?
allow mocking without dependency injection - this one isn't clear to me. Can you elaborate?
我認(rèn)為這來自 Motivation wiki 頁面,他們?cè)谄渲忻枋隽艘环N將代碼重構(gòu)為不調(diào)用靜態(tài)方法使其可測試.對(duì)于我認(rèn)為他們正在處理的具體示例,假設(shè)您有這段代碼,并且您想測試模擬靜態(tài)方法行為的方法,而不使用 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!
...
}
}
一種解決方案是將靜態(tài)調(diào)用拉到它自己的對(duì)象中,然后注入一個(gè)可以在測試時(shí)模擬的對(duì)象.例如,在不使用其他框架的情況下,這可能如下所示:
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();
...
}
}
我已經(jīng)將我的方法的行為與靜態(tài)調(diào)用的行為分開,并且可以在測試時(shí)使用 DI 構(gòu)造函數(shù)輕松地注入模擬.當(dāng)然,使用 powermock 我可以在適當(dāng)?shù)奈恢媚M靜態(tài)方法,然后使用它運(yùn)行.
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 時(shí)我是否需要犧牲一些東西?
And do I need to sacrifice something when using PowerMock?
物理上不,但我會(huì)說哲學(xué)上是:).以下是我的觀點(diǎn),我試圖給出很好的理由,但當(dāng)然它們是觀點(diǎn),所以請(qǐng)持保留態(tài)度:
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 發(fā)生的潛在可怕的事情是,為了完成模擬私有和靜態(tài)方法的壯舉,它們使用自定義類加載器(在生產(chǎn)運(yùn)行時(shí)不應(yīng)存在)并更改字節(jié)碼你的課.可以說,在大多數(shù)情況下,這對(duì)于絕大多數(shù)類來說都無關(guān)緊要,但如果你考慮一下,如果字節(jié)碼發(fā)生了變化,并且某些副作用不再存在,那么你實(shí)際上是在根據(jù)你的現(xiàn)有的類.是的,這是一個(gè)非常學(xué)術(shù)的論點(diǎn).
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 的良好綜合集成和更高級(jí)別的測試,您可以在一定程度上緩解第一個(gè)論點(diǎn).通過這種方式,即使您的單元測試使用的是 PowerMock,您也可以對(duì)對(duì)象的行為更有信心.
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.
我反對(duì) PowerMock 的另一個(gè)論點(diǎn)是,它幾乎太容易成為拐杖.我同意 PowerMock 可以幫助測試使用遺留代碼和您無法控制的其他代碼的代碼.但是我認(rèn)為,當(dāng)您可以控制需要模擬的類時(shí),您應(yīng)該避免使用它.如果您編寫一個(gè)帶有私有方法或靜態(tài)方法的類,您需要顯式地模擬以測試其他方法,我的直覺會(huì)說這個(gè)方法可能做得太多,應(yīng)該重構(gòu)和分解.PowerMock 已經(jīng)在項(xiàng)目中可用,您可能會(huì)想模擬它并繼續(xù)前進(jìn),這將減輕應(yīng)該鼓勵(lì)您重構(gòu)相同的痛苦.是的,有時(shí)由于各種技術(shù)和非技術(shù)限制,這是不可能的,但解決痛點(diǎn)而不是避免它們是件好事:)
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 :)
這篇關(guān)于PowerMock + Mockito VS Mockito 單獨(dú)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!