用Java测试紧密耦合的类

时间:2018-04-07 10:27:16

标签: java unit-testing junit

我有这个原始代码:

public SomeClass(int parameter) {
        this.someProperty = parameter;
        this.apiObject = new SomeApiClass(someProperty);
        for(i=0; i < 2; i++)
            apiObject.setApiProperty(i, "Hello World");
    }

代码完美无缺。但是当我尝试测试时会出现问题。

    @Mock
    private SomeApiClass someApiClass;

    private SomeClass someClass;


    @Before
    public void setUp() throws Exception {
        someClass = new SomeClass(3);
    }

    @Test
    public void shouldCreateSomeClass() {
        verify(someApiClass, times(2)). setApiProperty(anyInt(),anyString());
    }

我理解为什么这个测试不会通过。如果我将构造函数更改为:

,这将有效
public SomeClass(int parameter, SomeApiClass someApiClass) {
    ...
}

如果我不想将SomeApiClass注入构造函数并且无法在其中提供任何getter,我如何测试原始代码。

PS:请忽略代码中的拼写错误。即时输入。

1 个答案:

答案 0 :(得分:2)

在设计类时考虑可测试性以及区分参数和依赖性是很好的。

依赖关系是类依赖于完成其工作的对象。它们通常不会在依赖对象的整个生命周期内发生变化。

参数比依赖项更本地化。预计它们会在对对象方法的调用之间发生变化。

在原始代码中,看起来SomeClass的构造函数中的工作应该真正进入方法:

public class SomeClass {


    public void doWork(int parameter) {
        //
    }

}

在方法内部,如果您只对使用参数实例化SomeApiObject感兴趣,那么为什么不遵循Demeter法则并直接传递SomeApiObject作为参数:

public void doWork(SomeApiObject someApiObject) {
    //
}

然后消费者完成工作:

someClass.doWork(new SomeApiObject(3));

可以通过传入模拟的SomeApiObject作为参数进行测试:

//act
someClass.doWork(mockedSomeApiObject);

//assert
verify(mockedSomeApiObject).someVerification();

但是,如果您想要参数和依赖项的组合,可以使用Factory作为依赖项:

public class SomeClass {

    private final SomeApiObjectFactory someApiObjectFactory;

    public SomeClass(SomeApiObjectFactory someApiObjectFactory) {
        this.someApiObjectFactory = someApiObjectFactory;
    }

    public void doWork(int parameter) {
         SomeApiObject someApiObject = someApiObjectFactory.create(parameter);
         //etc
    }

然后你现在可以测试这个类了,因为你有办法提供可以验证哪些行为的模拟:

SomeApiObject mockSomeApiObject = Mockito.mock(SomeApiObject.class); 
when(mockSomeApiObjectFactory.create(anyInt()).thenReturn(mockApiObject);

除了所有这些之外,还有一些方法可以使用Powermockito测试你的原始类,因为它没有改变但是这些并不理想,如果可能的话最好重构,这样你就可以使用普通的Mockito进行测试。这会给你很好的OO习惯。祝你好运!