java 在使用Maven进行单元测试时,写入临时文件的正确方法是什么?

cfh9epnr  于 2023-05-21  发布在  Java
关注(0)|答案(7)|浏览(102)

我已经写了一个单元测试,它将一个文件写入文件系统,但没有给出它写入工作目录的路径;因此,如果从项目目录执行,则写入项目根目录,如果在项目父目录中执行,则写入父根目录。
那么,写入目标目录的正确方法是什么呢?很可能是目标目录中的一个目录?
如果我简单地在文件中指定target/,它将写入父项目目标,而不是项目目标。

UPDATE:实际上我需要测试完成后的文件。该文件用于需要发送给第三方的第三方提取格式。可以打开/关闭测试,以便仅在文件格式更改以重新批准时才运行。这不是一个大问题的文件去,但我想的东西,很容易找到。

monwx1rj

monwx1rj1#

您可以尝试使用TemporaryFolder JUnit @Rule,如here所述
TemporaryFolder在系统属性java. io. tmpdir指定的默认临时文件目录中创建一个文件夹。方法newFile在临时目录中创建一个新文件,newFolder创建一个新文件夹。
当测试方法完成时,JUnit会自动删除TemporaryFolder中的所有文件和目录,包括TemporaryFolder。JUnit保证删除资源,无论测试通过还是失败。

问题更新后

您可以更改maven-surefire-plugin使用的工作目录。

<plugins>
    [...]
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12.3</version>
        <configuration>
          <workingDirectory>${project.build.directory}</workingDirectory>
        </configuration>
      </plugin>
    [...]
</plugins>

您可以将该工作目录更改为测试所需的任何目录,如${project.build.directory}/my_special_dir/
surefire插件中的工作目录只影响正在运行的测试,并且仅适用于maven正在进行的测试。如果从IDE中运行测试,则工作目录将是其他目录。

72qzrwbm

72qzrwbm2#

不需要重新发明轮子。。
JDK提供了一种创建临时文件的方法,以及一种在退出时自动删除它的方法:

File file = File.createTempFile( "some-prefix", "some-ext");
file.deleteOnExit();

使用该文件,当您的测试完成时,它将自动删除。这就是全部。
要指定用于临时文件的目录,请使用重载方法:

File file = File.createTempFile( "prefix", "ext", new File("/some/dir/path"));
62lalag4

62lalag43#

我会写一个例程来确定文件应该被写到哪里,然后我会进行unittest,一般来说,我会尽量避免(尽可能地)在unittest中访问持久数据,比如文件IO或数据库访问,这也有性能原因和其他原因。
看看这个asnwer:https://stackoverflow.com/a/8032504/395659

hs1rzwqc

hs1rzwqc4#

您可能希望能够从IDE和Maven运行测试,因此最佳实践是编写测试,使其不会假定在Maven中运行。
处理临时文件的最佳方法之一是使用junit rules。这允许您依赖规则来为您清理。

dldeef67

dldeef675#

事先声明,我强烈反对在单元测试中做这样的事情。我还没有真正尝试过,但它应该工作:
假设你使用的是surefire插件,从它引用的文档中可以通过System.getProperty("basedir")访问被测项目的基目录。获取它并在basedir/target下创建文件。
一个更“合适”的方法(因为我们可能有机会将输出目录配置为其他目录,您可以将surefire插件配置更改为如下所示:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <systemPropertyVariables>
            <myOutDir>${project.build.outputDirectory}</myOutDir>
        </systemPropertyVariables>
    </configuration>
</plugin>

然后,您可以在测试中通过System.getProperty("myOutDir")获得实际的输出目录。

balp4ylt

balp4ylt6#

应在临时目录中创建临时文件。使用调用System.getProperty("java.io.tmpdir")检索它
临时文件应该是临时的,即在不需要时应将其移除。为了实现这一点,不要忘记在finally块中或在测试后运行的代码中删除它,即:

File tmpFile = ...
try {
   // deal with tempFile
} finally {
    tempFile.delete();
}

和/或

public class MyTestCase {
    private File tmpFile = null;

    @Before
    public void setUp() {
        tmpFile = ...;
    }

    @Test
    public void setUp() {
        // deal with tmpFile
    }

    @After
    public void setUp() {
        tmpFile.delete();
    }
}

如果可能,使用File.createTempFile(String prefix, String suffix),即然后你可以使用createTempFile()生成的具有特殊名称的文件。
使用file.deleteOnExit()。这将创建一个钩子,当JVM终止时,钩子会自动删除文件。只有当JVM被kill -9杀死时,该文件才会保留,因此它没有机会运行关闭代码。

9rygscc1

9rygscc17#

从JUnit 5开始,您可以使用@TempDir。测试结束后将删除(包括其内容)。
每个测试都有一个临时目录:

@Test
void testWithTempFiles(@TempDir Path tempDir) 
    Path file = tempDir.resolve("temp_file.txt");
    ...
}

或者一个用于类中的所有测试:

@TempDir
static Path tempDir

@Test
void testWithTempFiles() 
    Path file = tempDir.resolve("temp_file.txt");
    ...
}

相关问题