我正在使用一些遺留代碼,我必須實現一個新的處理程序。而在此處理程序,還有這是不幸的是由框架使用一些硬編碼的屬性文件初始化的對象,像這樣:這是可能的Mockito:when(SomeClass.getIntance())。然後返回(myMock)?
// new code
public class NewHandler extends RootHandler {
Util util = Util.getInstance(); // !!!Problem: throws NPE in unit-testing env
// defined in the legacy framework, can't change its signature
@Override
public void doSth() {
}
}
// legacy code
public class Util {
static public synchronized Util getInstance() {
if (_instance == null) {
_instance = new Util();
}
return _instance;
}
private Util() {
MyObj obj = LegacyCode.load("myConfig.cfg"); // !!!Problem: throws NPE in unit-testing env
...
}
}
現在的問題:在Util()
,它總是從一個固定的位置加載配置文件,因此當我運行我的單元測試時它總是拋出NPE,因爲單元測試類路徑中沒有「myConfig.cfg」。
一個解決方法是,以提取業務邏輯到一個單獨的方法,傳遞在util對象,這樣我可以在測試過程中在模擬對象傳遞:
// new code
public class NewHandler extends RootHandler {
Util util = null;
// defined in the legacy framework, can't change its signature
@Override
public void handle() {
Util util = util.getInstance();
doHandle(util);
}
public void doHandle(Util util) {
...
}
}
// legacy code
public class Util {
...
}
我的問題是:
是否有任何其他方式來解決此問題,而不添加doHandle()方法?我試着用了的Mockito下面的代碼:
Util myUtil = mock(Util.class);
when(Util.getInstance()).thenReturn(myUtil);
,但它沒有工作,Util.getInstance()沒有得到與myUtil取代。
有什麼想法?
UPDATE:事情變得有點混亂,因爲我發現Util.getInstance()在遺留代碼庫中無處不在。所以,即使我在我的新代碼中使用了一個嘲諷的Util(如下面的Stas所描述的),當Util.getInstance()在其他地方調用時,事情仍然會中斷。
很顯然,我無法將新構造函數添加到調用Util.getInstance()的遺留代碼中的每個類中。
這是我問的原因「是否有可能有一些的Mockito像時(Sth.getInstance())。thenReturn(myMock)」
如果是,則所有來電到Util.getInstance()可以被嘲笑,不會再造成問題。
嗯....任何想法?
****************************************** *************************
SOLUTION:我想在我的情況的解決方案是PowerMock
對於額外的獎金,加上它調用'這個(Util.getInstance())默認的構造函數;'所以你的正常工作代碼像以前一樣。 – ZeissS 2011-04-19 10:18:52
@ZeissS,我不會在新代碼中這樣做。我認爲類應該在「正常代碼」和測試中以相同的方式使用。但作爲解決遺留代碼的解決方案,它可能是一個很好的解決方案。 – 2011-04-19 10:30:12
@Stas Kurilin:我的意思是僅僅爲了向後兼容。當然,新代碼應該使用工廠或一些其他的意志主義來解決這些依賴關係。 – ZeissS 2011-04-19 10:33:52