2013-02-28 45 views
3

我有第三方組件,我想嘲笑,但它返回類具有複雜的層次結構和一些接口具有靜態字段初始化一些類不提供API。我不需要任何隱藏課程。模擬類與缺少的依賴關係

示例: 假設我們要模擬實現Combo的類MutableCombo。但是接口組合具有由Breaker初始化的字段。破壞程序是實現程序包的一部分,在編譯和測試期間不能由開發人員訪問。

public interface Combo{ 
    String FUU = Breaker.getFoo(); 
    String BAR = Breaker.getBar(); 
} 
public class MutableCombo implements Combo; 

我想測試我的課與MutableCombo工作,但不能嘲笑,因爲

java.lang.NoClassDefFoundError: Breaker 
    at Combo.<clinit>(Combo.java:36) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:169) 
+0

你是什麼意思的'部分實施包'? – CAMOBAP 2013-02-28 08:26:40

+0

我使用第三方組件。組件有2個部分 - API和實現包。作爲開發人員,我只能使用組件的API部分。 – ainlolcat 2013-02-28 08:28:27

回答

3

您會在這裏需要一個適配器。你不應該嘲笑你沒有的初學者類型。將MutableCombo視爲實現細節。例如:

public class ExampleMutableCombo implements IExampleMutableCombo 
{ 
    public String DoFoo() 
    { 
     return Breaker.getFoo(); 
    } 

    public String DoBar() 
    { 
     return Breaker.getBar(); 
    } 
} 

使您的代碼使用IExampleMutableCombo。這個界面現在是你的。在你的生產代碼中使用它。當你擁有這個接口,你可以模擬這個角色 - 你可以引入一個假的組合進行測試,如:

public class FakeExampleMutableCombo implements IExampleMutableCombo 
{ 
    public String DoFoo() 
    { 
     return "Foo"; 
    } 

    public String DoBar() 
    { 
     return "Bar"; 
    } 
} 

現在所有的測試可以用掐滅類工作,而你的產品代碼可以利用的ExampleMutableCombo。關鍵是「編碼到接口」,而不是一個類型。

+0

基本上我們這樣做。但是很煩人。我希望有一些暴力解決方案),但正如我在答案中看到的那樣,並沒有。 – ainlolcat 2013-03-13 12:27:30

+0

@ainlolcat它可能會令人討厭,但這是一個很好的做法。將盡可能多的第三方代碼推到系統邊緣。您的域名應該是重點。剩下的只是你應該可以自由交換的細節,只要它們符合你期望的界面。以您的例子中的Breaker爲例,我可以使用MyBreaker切換它。只要它吐出Foo和Bar,應用程序的其餘部分都不會在意。現在使用數據庫或WebService替換Breaker,並且您擁有強大的功能,可以輕鬆地更改程序。 – Finglas 2013-03-13 13:36:38