如果设置了属性,我会创建一个目录。现在,每次运行测试时,都会在我的FileSystem中创建目录。我有办法模拟文件/文件系统吗?
待测班级:
@Service("InitializeEnvironment")
public class EnvironmentChecker implements InitializingBean {
@Value(value="${delivered_dir}")
private String delivered_dir;
@Override
public void afterPropertiesSet() throws Exception {
if (!StringUtils.isEmpty(delivered_dir)){
File dir = new File(delivered_dir);
if (!dir.exists()) {
dir.mkdirs();
}
}
}
}
单元测试
public class EnvironmentCheckerTest {
@Test
public void testMailHostNichtGesetzt() throws Exception{
EnvironmentChecker environmentChecker = new EnvironmentChecker();
setValue(environmentChecker, "delivered_dir", "./");
environmentChecker.afterPropertiesSet();
}
private void setValue(Object target, String fieldname, Object value){
Field field = ReflectionUtils.findField(target.getClass(),fieldname);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, target, value);
}
答案 0 :(得分:2)
首先,重要的是要问:这个测试的价值是什么?
可能是您简化了示例,但所有afterPropertiesSet()
方法都是在磁盘上创建一个目录,这取决于一些非常简单的前置条件。在文件系统上创建目录是副作用,并且(至少在我看来)带有副作用的代码不适合单元测试。
为什么呢?因为副作用是否发生完全超出了应用程序逻辑的范围。它是否实际发生取决于代码控制之外的许多事情 - 顶部的java文件api,一直到实际在生产机器上进行写入的物理磁盘。
我会用另一种方式 - 即使你嘲笑文件系统,你获得了什么?您可以获得将目录写入模拟文件系统的知识,而不是更多。那是什么意思?它有什么价值吗?它是否能让您对系统在生产中的表现如何表现更有信心?
任何这样的代码只产生副作用,只有非常简单(即太简单测试)的业务逻辑,定义副作用是否应该发生,不应该在第一名。它没有任何价值。
如果在您的实际代码中存在确定是否发生副作用的复杂业务逻辑,那么我的建议是将产生副作用的代码抽象到另一个类中。然后,您可以在现有类中轻松模拟它,以测试它周围的“纯粹”业务逻辑。
请让我强调一点,我并不主张不应该对这种副作用进行测试。我只是说单元测试是测试它们的错误方法。相反,请在生产硬件上进行自动(或手动!)集成测试。