Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用TDD开发Java文件遍历代码_Java_Unit Testing_Junit_Tdd - Fatal编程技术网

用TDD开发Java文件遍历代码

用TDD开发Java文件遍历代码,java,unit-testing,junit,tdd,Java,Unit Testing,Junit,Tdd,我必须实现一些代码来遍历目录结构并返回找到的文件列表。要求非常简单: 给定一个基本目录,查找其中的所有文件(不是目录本身) 如果找到目录,请对其重复步骤1 我想用TDD开发代码。当我开始编写测试时,我意识到我在模拟classFile,因此我可以拦截对File.isDirectory()等的调用。通过这种方式,我强迫自己使用一种我将调用该方法的解决方案 我不喜欢它,因为这个测试肯定与实现紧密耦合。如果我改变了询问文件是否是目录的方式,那么即使我保持契约工作,这个测试也会失败。把它当作一个例子让我感

我必须实现一些代码来遍历目录结构并返回找到的文件列表。要求非常简单:

  • 给定一个基本目录,查找其中的所有文件(不是目录本身)
  • 如果找到目录,请对其重复步骤1
  • 我想用TDD开发代码。当我开始编写测试时,我意识到我在模拟class
    File
    ,因此我可以拦截对
    File.isDirectory()
    等的调用。通过这种方式,我强迫自己使用一种我将调用该方法的解决方案

    我不喜欢它,因为这个测试肯定与实现紧密耦合。如果我改变了询问文件是否是目录的方式,那么即使我保持契约工作,这个测试也会失败。把它当作一个例子让我感到不安,因为在那篇文章中表达了所有的理由。我不确定这是否是我需要使用这种测试的情况之一。另一方面,我真的想确保它返回的每个文件都不是一个目录,遍历整个结构。对我来说,这需要一个好的、简单的测试

    我希望避免创建一个带有“磁盘上”真实测试文件的测试目录结构,因为我认为它相当笨拙,而且与我读过的一些最佳实践背道而驰

    请记住,我不需要对内容执行任何操作,因此使用
    StringReader
    而不是
    FileReader
    之类的技巧在这里不适用。不过,我认为我可以做一些类似的事情,比如在设置测试时能够在内存中创建目录结构,然后将其拆下。我还没找到办法

    您将如何使用TDD开发此代码


    谢谢

    对于需要超过几毫秒才能完成的单元测试,我非常不安,因此强烈建议模拟文件I/O

    但是,我认为您不应该直接模拟
    文件
    类。相反,请将
    文件
    类的使用视为“如何”,并尝试识别“什么”。那么

    例如:您提到您要做的一件事是拦截对
    File.isDirectory
    的调用。与其与
    文件
    类交互,不如让代码与接口的某些实现交互,如:

    public interface FileSystemNavigator {
        public boolean isDirectory(String path);
    
        // ... other relevant methods
    }
    

    这会将
    文件.isDirectory的使用隐藏在代码的其余部分,同时隐藏在与程序更相关的部分。

    您犯的错误是模拟
    文件。有一种测试反模式假设如果您的类委托给类
    X
    ,您必须模拟类
    X
    ,才能测试您的类。还有一条一般规则,就是在编写进行文件I/O的单元测试时要谨慎,因为它们往往太慢。但在单元测试中并没有绝对禁止文件I/O

    在单元测试中,设置并拆除临时目录,并在该临时目录中创建测试文件和目录。是的,您的测试将比纯CPU测试慢,但它们仍然很快。JUnit甚至有支持代码来帮助实现这个场景:一个
    临时文件夹上的
    @Rule


    就在本周,我使用TDD实现了一些内务代码,这些代码必须扫描目录并删除文件,所以我知道这是可行的。

    一个选项是,但通常我只使用“真实”文件访问,让我的测试使用一个特殊的目录进行测试。@DavidWallace你应该把它作为一个答案。谢谢@DavidWallace!我想Commons VFS对我来说可能是一种过度的杀伤力。拥有一个“真实”的文件结构简化了测试,并使其与实现的耦合性大大降低。我试试看!是的,我发现使用真实文件效果很好。不过也有一些问题。您确实希望为每个测试方法提供自己的子目录,以消除测试相互交互的可能性。并确保测试在运行之前和之后都会清理自己的目录,以防它在上一次运行测试时中途终止,并留下一些不需要的文件。