是否存在用于递归比较目录的匹配器?

时间:2015-08-04 08:10:57

标签: java recursion junit hamcrest

我正在编写IM和导出文件的单元测试。我需要逐个字节地递归测试生成的目录。我自己为平面目录实现了一个例程,并且知道如何递归地执行此操作。但我不想重新发明轮子。

那么有类似下面的例子吗?

Matchers.matches(Path actual, equalsRecursive(Path value));

FileAssertions.equalsRecursive(Path actual, Path value);

2 个答案:

答案 0 :(得分:2)

我不知道这样的匹配器。所以,IMO你必须自己做。 我能想到的2个选项如下:

  1. 使用Apache Commons FileUtils以便

    1.1。确保每个文件/子目录(递归调用都在这里)存在于当前正在测试的目录中。对于每个子目录获取一组文件,迭代并使用directoryContains方法作为相应的子目录。

    1.2使用contentEquals方法确保2个相应文件的内容相等。如果您将2个目录传递给此方法,我不确定会发生什么。

  2. 第二个选项:如果您在Linux上运行测试,则可以使用Runtime.exec()文档here从Java运行Linux命令。您需要运行的单个命令是diff -r <directory1> <directory2>

  3. 祝你好运!

答案 1 :(得分:2)

没找到任何东西。所以我自己编程。它对于大型文件来说并不是非常复杂和缓慢,但似乎有效。

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;

import org.junit.Assert;

/**
 * Assertion for recursively testing directories.
 * 
 * @author andreas
 */
public class AssertFile {

private AssertFile() {
    throw new RuntimeException("This class should not be instantiated");
}

/**
 * Asserts that two directories are recursively equal. If they are not, an {@link AssertionError} is thrown with the
 * given message.<br/>
 * There will be a binary comparison of all files under expected with all files under actual. File attributes will
 * not be considered.<br/>
 * Missing or additional files are considered an error.<br/>
 * 
 * @param expected
 *            Path expected directory
 * @param actual
 *            Path actual directory
 */
public static final void assertPathEqualsRecursively(final Path expected, final Path actual) {
    Assert.assertNotNull(expected);
    Assert.assertNotNull(actual);
    final Path absoluteExpected = expected.toAbsolutePath();
    final Path absoluteActual = actual.toAbsolutePath();
    try {
        Files.walkFileTree(expected, new FileVisitor<Path>() {

            @Override
            public FileVisitResult preVisitDirectory(Path expectedDir, BasicFileAttributes attrs)
                    throws IOException {
                Path relativeExpectedDir = absoluteExpected.relativize(expectedDir.toAbsolutePath());
                Path actualDir = absoluteActual.resolve(relativeExpectedDir);

                if (!Files.exists(actualDir)) {
                    Assert.fail(String.format("Directory \'%s\' missing in target.", expectedDir.getFileName()));
                }

                Assert.assertEquals(String.format("Directory size of \'%s\' differ. ", relativeExpectedDir),
                        expectedDir.toFile().list().length, actualDir.toFile().list().length);

                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFile(Path expectedFile, BasicFileAttributes attrs) throws IOException {
                Path relativeExpectedFile = absoluteExpected.relativize(expectedFile.toAbsolutePath());
                Path actualFile = absoluteActual.resolve(relativeExpectedFile);

                if (!Files.exists(actualFile)) {
                    Assert.fail(String.format("File \'%s\' missing in target.", expectedFile.getFileName()));
                }
                Assert.assertEquals(String.format("File size of \'%s\' differ. ", relativeExpectedFile),
                        Files.size(expectedFile), Files.size(actualFile));
                Assert.assertArrayEquals(String.format("File content of \'%s\' differ. ", relativeExpectedFile),
                        Files.readAllBytes(expectedFile), Files.readAllBytes(actualFile));

                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                Assert.fail(exc.getMessage());
                return FileVisitResult.TERMINATE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                return FileVisitResult.CONTINUE;
            }

        });
    } catch (IOException e) {
        Assert.fail(e.getMessage());
    }
}

}