如何对依赖于其他方法的方法进行单元测试
How to unit test methods with dependencies on other methods
我有以下方法
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
使访问外部资源(例如文件系统)的代码可进行单元测试的最佳方法是创建抽象层,例如:
public class FileAccessor {
public String getProperty(ConfigProperties property) {
// property file access code goes here
}
public File createFile(String filePath) {
return new File(filePath);
}
}
然后,class-under-test可以重构为使用resource-accessor通过构造函数注入的依赖:
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));
}
}
我有以下方法
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
使访问外部资源(例如文件系统)的代码可进行单元测试的最佳方法是创建抽象层,例如:
public class FileAccessor {
public String getProperty(ConfigProperties property) {
// property file access code goes here
}
public File createFile(String filePath) {
return new File(filePath);
}
}
然后,class-under-test可以重构为使用resource-accessor通过构造函数注入的依赖:
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));
}
}