如何使用 JUnit 在 Java Spring 引导中测试移动文件

How to Test Move File in Java Spring Boot with JUnit

我有一个 java Spring 引导应用程序,它在未处理目录中查找文件,处理文件,然后将其移动到已处理目录。我正在尝试使用 JUnit 编写集成测试来测试移动是否成功。

为此,我在 src/test/resources 中创建了一个子目录树,它反映了服务器上的目录。这样测试就不会绑定到任何一台计算机或服务器。

当我尝试 运行 测试时,我得到了 java.nio.file.DirectoryNotEmptyException

以下是我的集成测试的全文。我的想法是我有一个测试文件 test_file.csv 永久存在于我的 src/test/resources 目录中。对于集成测试,我想复制该文件,并将其写入 src/test/resources/foo/bar/Unprocessed。如果被测试的移动逻辑有效,test_file.csv 应该最终出现在 src/test/resources/foo/bar/Processed 文件夹中。 ProcessedUnprocessed 目录在测试开始时都是空的。

如何让这个测试不报错?提前致谢。

@Test
public void processAndMoveSuccessTest() throws IOException {
    File originalFileLocation = ResourceUtils.getFile("classpath:test_file.csv");
    System.out.println(originalFileLocation.getParent());
    String firstPart = originalFileLocation.getParent();
    String modifiedFilePath = firstPart.replaceAll("src\\test\\resources\\","src\\test\\resources\\foo\\bar\\Unprocessed\\");
    File unprocessedFile = new File(modifiedFilePath);
    Path originalFileLocationPath = Paths.get(originalFileLocation.getPath());
    unprocessedFile.delete();
    Assert.assertFalse(!unprocessedFile.exists());

    Path unprocessedFilePath = Paths.get(unprocessedFile.getPath());
    File processedFile = new File("src\\test\\resources\\foo\\bar\\Processed\\test_file.csv");
    Assert.assertFalse(processedFile.exists());

    Files.copy(originalFileLocationPath, unprocessedFilePath, StandardCopyOption.REPLACE_EXISTING);
    Assert.assertTrue(processedFile.exists());

    int beforeProcess = repo.count();
    Assert.assertNotNull(beforeProcess);
    Assert.assertTrue(beforeProcess > 0);
    File testFile = importService.processAndMoveFile(unprocessedFile);
    int afterProcess = repo.count();
    Assert.assertTrue(afterProcess > beforeProcess);

    Assert.assertEquals(processedFile.getPath(), testFile.getPath());
    processedFile.delete();
}

涉及目录的测试最复杂的部分是,如果您的测试意外失败或出错,您的环境中将存在一堆松散的文件。

出于理智考虑,我建议使用 deleteOnExit(); as you create files and directories

此功能允许您在执行完成后将文件标记为删除。

File file = new File("test.txt");
Assert.assertTrue(!file.exists());
file.createNewFile();
throw new Exception("Foo");
file.delete();

这个测试可以运行一次,之后它会不断地断言失败。

File file = new File("test.txt");
file.deleteOnExit();
Assert.assertTrue(!file.exists());
file.createNewFile();
throw new Exception("Foo");
file.delete();

使用 deleteOnExit 的这个测试可以 运行 重复而断言不会失败。

如果您正在创建一个目录,它遵循 FILO。

File foo = new File("foo");
foo.mkdir();
foo.deleteOnExit();
File bar = new File("foo/bar.txt");
bar.createNewFile();
bar.deleteOnExit();

这将首先删除bar,然后删除foo。如果 bar 没有被删除,Foo 将不会被删除,所以通过在创建资源和子资源时声明 deleteOnExit 来遵循拆解。