2011-04-19 38 views
1

我正在使用一些遺留代碼,我必須實現一個新的處理程序。而在此處理程序,還有這是不幸的是由框架使用一些硬編碼的屬性文件初始化的對象,像這樣:這是可能的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

回答

1

你應該嘗試像SMT

public class NewHandler extends RootHandler { 
    Util util; 
    //Pass instance 
    NewHandler(Util util) {this.util = util;} 
} 

比你將能夠使用它在測試中new NewHandler(Util.getInstance())new NewHandler(mock(Util.class))

PS進一步的信息,你可以瞭解Service locatorDI

+1

對於額外的獎金,加上它調用'這個(Util.getInstance())默認的構造函數;'所以你的正常工作代碼像以前一樣。 – ZeissS 2011-04-19 10:18:52

+0

@ZeissS,我不會在新代碼中這樣做。我認爲類應該在「正常代碼」和測試中以相同的方式使用。但作爲解決遺留代碼的解決方案,它可能是一個很好的解決方案。 – 2011-04-19 10:30:12

+0

@Stas Kurilin:我的意思是僅僅爲了向後兼容。當然,新代碼應該使用工廠或一些其他的意志主義來解決這些依賴關係。 – ZeissS 2011-04-19 10:33:52

相關問題