2012-03-02 66 views
0

我對如何爲依賴項提供默認值以及如何處理它們的測試存在一些疑問。 比方說,我有類,如下所示:默認的依賴項實現,如何處理沒有DI框架?

class MyService { 
    private AnotherService dependency; 
    ... 
} 

由於這是遺留應用程序不存在依賴注入(甚至是土生土長一個)。 所以提供依賴有幾種方法(例如構造函數,setter)。 但我想提供這種依賴的默認實現,但我不確定如何去做。

我具有

class MyService { 
    private AnotherService dependency = new AnotherServiceImpl(); 
    ... 
} 

但隨後被創建爲MyService時,這種依賴總是初始化做到這一點。對於測試我不想要這個,因爲我想提供模擬impl。我覺得像

class MyService { 
    private AnotherService dependency; 

    private AnotherService getDependency() { 
     if(dependency == null) { 
      dependency = new AnotherService(); 
     } 
     return dependency 
    } 

    setDependency(AnotherService dependency) { 
     this.dependency = dependency; 
    } 
} 

現在,如果所有depedency呼叫通過getDependency()完成第一,依賴裝載懶惰的方式,我認爲,我可以把我自己的測試。

我知道很難開始在遺留代碼中引入諸如依賴注入之類的改變,而這些改變已經不存在了。例如。如果我在構造函數中提供依賴關係,則依賴實例化的問題只會向上移一層。

第二個問題是如果現在只有一個實現,如何提供依賴關係。我正在使用Mockito,它的@InjectMocks可以將模擬注入私人領域。我想知道是否需要暴露setDependency或構造函數arg依賴,並使這一個impl與接口?它不是現在過度工程嗎?我不想只爲了測試而改變我的代碼。

回答

1

常見的patterm是重載的構造函數:

class MyService { 
    private AnotherService dependency; 

    MyService() { 
     this(new AnotherServiceImpl()); 
    } 

    MyService(AnotherService dependency) { 
     this.dependency = dependency; 
    } 

    ... 
} 

現有代碼的工作如前,通過調用默認的構造函數,而測試可以使用構造與注射依賴。

+1

+1這被稱爲*庶子注入*(防)模式,雖然我很少推薦它用於綠地開發,它作爲遺留代碼庫中的重構很有意義。這裏有更多關於這種模式:http://stackoverflow.com/questions/6733667/is-there-an-alternative-to-bastard-injection-aka-poor-mans-injection-via-defa/6739953#6739953 – 2012-03-02 11:49:05

0

您可以使用Abstract Factory作爲您的依賴關係。

class MyService { 
private AnotherService dependency; 
private static ServiceFactory serviceFactory = ServiceFactory.getInstance(); 
... 
public void action() { 
    ... 
    AnotherService dependency = serviceFactory.getAnotherService(); 
    ... 
} 
} 

單元測試應該更容易。只需從ServiceFactory類的測試用例中返回模擬實現即可。

在DI框架開始流行之前 - 抽象工廠模式被廣泛使用。

相關問題