如何使用依赖于其他方法的单元测试方法

时间:2018-03-11 22:35:19

标签: java junit5

我有以下方法

public static File getInventoryFileFromProperties(){
    String filePath = getProperty(ConfigProperties.MY_INVENTORY_FILE);
    logger.debug("Looking for inventory file at {}", filePath);

    return new File(filePath);
}

如何针对以下条件对此进行单元测试,属性文件中不存在ConfigProperties.MY_INVENTORY_FILE。

getProperty() // gets values from property file
ConfigProperties.MY_INVENTORY_FILE // is an enum of keys 

1 个答案:

答案 0 :(得分:2)

创建访问外部资源的代码(例如文件系统)单元可测试的最佳方法是创建抽象层,例如:

public class FileAccessor {        
    public String getProperty(ConfigProperties property) {
        // property file access code goes here
    }

    public File createFile(String filePath) {
        return new File(filePath);
    }        
}

然后,可以重构被测试类以通过依赖项的构造函数注入来使用资源访问器:

public class ContainingClass {

    private FileAccessor fileAccessor;

    // this constructor is accessible for the unit tests
    ContainingClass(FileAccessor fileAccessor) {
        this.fileAccessor = fileAccessor;
    }

    // this constructor is used by normal client code
    public ContainingClass() {
        this(new FileAccessor());
    }

    public File getInventoryFileFromProperties(){
        String filePath = fileAccessor.getProperty(ConfigProperties.MY_INVENTORY_FILE);
        return fileAccessor.createFile(filePath);
    }
}

最后,由于您可以模拟文件访问,因此单元测试变得更加简单。此测试使用Mockito模拟框架来模拟依赖项,并且还可以使用早期版本的JUnit:

import static org.mockito.Mockito.*;
import org.junit.Test;

public class ContainingClassTest {

    @Test
    public void getInventoryFileFromProperties_MY_INVENTORY_FILE_isMissing() {

        FileAccessor fileAccessor = mock(FileAccessor.class);

        // arrange the config file to return a null value for the property
        when(fileAccessor.getProperty(ConfigProperties.MY_INVENTORY_FILE)).thenReturn(null);

        // act; call the method
        new ContainingClass(fileAccessor).getInventoryFileFromProperties();

        // assert that the file-creating method was called with a null path
        verify(fileAccessor).createFile(isNull(String.class));
    }
}