如何在JUnit测试用例中比较文件?

22

我想在我正在开发的小项目中实现JUnit,因为我想学习一些关于它的知识。

我阅读的教程都提到了具有特定输出的方法。

对我来说,我的输出是文件,我该怎么做?有没有简单的例子?有哪些方法可以帮助我完成这个任务?

这些文件是由一个空私有方法生成的原始文本文件。


方法如何写入文件?如果它们得到一个流,你可以给它们自己的流,而不是指向一个文件的流,然后进行比较。 - Amir Rachum
使用基本的写入缓冲字符串功能,结合网络爬虫(当我按下回车键时它会输出消息),代码大致如下:txtUrlSpecial.write(bigText.charAt(j)); - Saikios
5个回答

24
你想为给定的输入获取正确的输出文件,并设置一个测试来调用带有这些输入的void方法,然后将你通过验证的输出文件与方法生成的文件进行比较。你需要确保有一种指定方法输出位置的方法,否则你的测试将非常脆弱。
@Rule
public TemporaryFolder folder = new TemporaryFolder();

@Test
public void testXYZ() {
    final File expected = new File("xyz.txt");
    final File output = folder.newFile("xyz.txt");
    TestClass.xyz(output);
    Assert.assertEquals(FileUtils.readLines(expected), FileUtils.readLines(output));
}

使用commons-io的FileUtils方便地比较文本文件,使用JUnit的TemporaryFolder确保测试运行之前输出文件不存在。


我喜欢这个,但为什么没有人投票给你的答案? :S - Saikios
2
你可以随时为它投票。 - Jon Freedman
Eclipse提示org.junit.internal.runners.TestClass已经过时=( - Saikios
你只需要导入 junit.framework.Assertorg.junit.Test,你正在使用 JUnit 4 吗? - Jon Freedman
我猜这个方法的使用必须限制在短文件中,因为输出结果难以阅读。例如,没有关于行号的任何信息。 - Jarekczek
@Jarekczek:我建议当你发现两个文件不同时,你可能想用一些其他的东西来比较它们,而不是使用一个失败的单元测试的标准输出,因为很可能存在不止一个差异 - 不要忘记单元测试的默认行为应该是始终通过... - Jon Freedman

3

静态方法 assertEquals,其作用是比较两个 Reader 对象的内容是否相同,若不同则抛出异常。其中参数包括一个字符串类型的提示信息、期望值和实际值两个 Reader 对象。此方法为保护级别。 - user482745

2
在你的方法完成文件写入后,在单元测试中,你可以读取该文件并验证是否正确地写入了数据。
另一件有意义的事情是将你的方法分成两部分:一个用于检索数据并将其返回给仅负责将其写入文件的方法。然后你可以验证第一个方法返回的数据是否正确。
另一种可行的方法是将一个OutputStream传递给写入数据的方法。在"真正的代码"中,你可以传递一个FileOutputStream / FileWriter,而在测试代码中,你可以编写一个模拟实现的OutputStream并检查写入到其中的内容。

1
如果您无法控制将输出放入流中的方法,那么我建议您重构代码,使该方法在参数(或其类的构造函数)中接收流。

之后,测试就非常容易了 - 您只需检查流即可。易于测试的代码通常等同于良好的代码。


问题在于实际上它并不会生成一个单一的文件,而是会根据不同的因素生成3到5个文件。但由于我对junit非常菜鸟,所以我想先尝试生成一个单一的文件,以完全理解它。谢谢=D。 - Saikios
@Saikios 这对于任意数量的文件都是相关的 :) - Amir Rachum

1

虽然你的问题看起来很简单,但它确实触及了单元测试的核心,我们需要编写良好格式化的代码以便于测试。这就是为什么一些专家建议先编写单元测试,然后再编写实现类。

针对你的情况,我建议你允许你的方法执行并创建所需的文件,随后你的单元测试可以分析这些文件是否正确形成。


谢谢,下次我会记住先编写单元测试的:D - Saikios
写整个文件的那段代码可能太大且复杂。JUnit 可以显示代码是否仍然有效(没有回归),这是一件好事。但是,真正好的单元测试也有助于发现哪些部分出了问题。 - Audrius Meškauskas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接