2013-02-28 94 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