【问题标题】:Refactor java static method to make it testable重构 java 静态方法以使其可测试
【发布时间】:2022-07-31 17:56:00
【问题描述】:

我想让这段代码可测试,但是在方法中创建的 URIFile 实例给我带来了问题。我无法为它们定义模拟行为,也不想使用 PowerMock,因为它们没有反映 Jacoco 的测试覆盖率。
如果可能的话,我们能否以某种方式重构代码。如果我们可以保留方法的静态性质,那将是更可取的。更改它会弄乱代码的其他部分。

public static List<String> getAbsoluteFilePaths(String dirUrl) throws URISyntaxException {
        URI uri = new URI(dirUrl);
        File folder = new File(uri);
        File[] fileList = folder.listFiles();
        List<String> fileNames = new ArrayList<>();

        if (fileList != null) {
            for (File file : fileList) {
                String fileOrDirUrl = uri.getScheme() + "://" +
                        (uri.getAuthority() != null ? uri.getAuthority() : "")+
                        file.getAbsolutePath();

                if (file.isFile())
                    fileNames.add(fileOrDirUrl);
                else if (file.isDirectory())
                    fileNames.addAll(getAbsoluteFilePaths(fileOrDirUrl));
            }
        }
        return fileNames;
    }

【问题讨论】:

  • but the URI and File instance created inside the method are giving me problems. - 究竟是什么问题?

标签: java unit-testing mocking refactoring static-methods


【解决方案1】:

除了在这种情况下模拟 FileURI 是否有用的问题之外,您还可以通过功能接口提取对象的创建。

    private static final Function<String, File> fileFactory = File::new;
    
    public static List<String> getAbsoluteFilePaths(String dirUrl) throws URISyntaxException {
        File folder = fileFactory.apply(dirUrl);
        
        URI uri = folder.toURI();
        File[] fileList = folder.listFiles();
        List<String> fileNames = new ArrayList<>();

        if (fileList != null) {
            for (File file : fileList) {
                String fileOrDirUrl = uri.getScheme() + "://"
                        + (uri.getAuthority() != null ? uri.getAuthority() : "")
                        + file.getAbsolutePath();

                if (file.isFile()) {
                    fileNames.add(fileOrDirUrl);
                } else if (file.isDirectory()) {
                    fileNames.addAll(getAbsoluteFilePaths(fileOrDirUrl));
                }
            }
        }
        return fileNames;
    }

【讨论】:

    【解决方案2】:

    根据specification,使用的类 File 的构造函数设置了一些必须满足的先决条件:例如,URI 必须是绝对的,它的方案必须是 'file' 并且它的权限必须是未定义的。

    因此,URI的构造可以留给方法File#toURI(),这样你就可以把方法分成两个可测试的部分:

    class SomeClass {
        public static List<String> getAbsoluteFilePaths(String dirUrl) throws URISyntaxException {
            URI uri = new URI(dirUrl);
            File folder = new File(uri);
            return getFileUris(folder);
        }
        
        public static List<String> getFileUris(File folder) {
            File[] fileList = folder.listFiles();
            List<String> fileNames = new ArrayList<>();
    
            if (fileList != null) {
                for (File file : fileList) {
                    if (file.isFile())
                        fileNames.add(file.toURI().toString());
                    else if (file.isDirectory())
                        fileNames.addAll(getFileUris(file));
                }
            }
            return fileNames;
        }
    }    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多