【问题标题】:Unit test multiline strings in JavaJava中的单元测试多行字符串
【发布时间】:2012-11-08 21:32:34
【问题描述】:

我想对一个用于解析特定模式的文件的 API 进行单元测试。
返回的文本片段可能是多行的并包含选项卡等。即文件中的文本使用新行和制表符进行格式化以供用户阅读(就像我们很好地缩进 xml 文件一样)。
问题:因为Java 不提供该选项定义这样的字符串(这将是对 API 输出的Assert 检查的预期结果)如何处理这些问题?
我想例如将所有预期的输出保存在带有某种特殊字符的文件中,以标记每个预期片段的开始和结束,但我认为也许有一个标准的方法来解决这个问题。
有更好的选择吗?

更新: 示例:

This is an example String.    
     This is an inner part of the string.        Another part.           Another also.    
                      This is also an inner part.   
     Now an outer.   This is the outer example       string.

【问题讨论】:

  • 我很困惑。选择格式有问题吗?为什么不选择你的测试格式呢?很可能 CSV 或 XML 是您可以查看的格式,而且这些格式非常规范。
  • 当您说返回的文本可能是“多行”时,是否意味着其中包含 '\n' 个字符?
  • 至少对于合理大小的字符串,"Hello\nWorld" 有什么问题?
  • @dimo414:我没有定义字符串。我从我将处理的示例文件中复制它们。但是我不能在 eclipse 中复制粘贴它们。
  • 不能在eclipse中复制粘贴?那时你的 Eclipse 安装有些混乱。

标签: java string unit-testing junit junit4


【解决方案1】:

更新:基于@Code-Guru 的回答(他说的显而易见):您可以轻松地做到这一点,以便 Eclipse 可以正确插入并自动转义您的文字,如果您愿意走内联路线:Windows->Preferences->Java->Editor->Typing->粘贴文字时转义文本

遗憾的是,Java 没有像 Scala 或 Groovy 这样的多行字符串。

我找到的最好的解决方案是在你的类路径中放一个文本文件并做一个

getClass().getResourceAsStream("filename");
//Then convert to string.

这将从相对于getClass() 类的类路径中加载一个名为filename 的文件(即在同一个包中)。

您可以在这里使用我的要点:https://gist.github.com/4041855,它使用 Guava 可以更轻松地将文件作为字符串从类路径加载并进行一些性感的缓存。

如果您使用 MavenGradle,您需要将这些文件放入 src/test/resources 而不是 src/test/java

如果您不想生成很多文件,显然可以对字符串(即 XML)进行一些解析。另一个稍微有点矫枉过正的选择是制作一个只读的 SQLite 数据库甚至是 CSV。我见过有人这样做,如果他们想要测试 1000 多个不同的参数。如果那是你的问题,你应该谷歌 JUnit 参数化测试

【讨论】:

  • 我不太明白。在你说的文本文件filename 中,你说的都是预期的Strings?所以你的建议也是使用文件?这是怎么回事?最好不要只使用Reader
  • 这真的取决于你的测试。字符串很好,因为它们是不可变的,可以放入 HashMaps 中,您可以在 String 上执行 assertEquals。我想我对你的要求感到困惑。检查我的编辑,看看它是否澄清。
  • 查看更新。这是一个示例字符串,如果它正常工作,我期望从 API 得到它。我有很多这样的字符串。你还说要将它们存储在一个文件中?但是如何CSV 适合这里吗?
  • 忽略 CSV 注释。所以你想用许多不同的字符串输出参数化一个测试。如果是这种情况,我认为 XML 可能是你最好的选择,否则我想说为每个测试输出制作一个文件。 XML 或任何格式的问题在于您必须使用句柄/知道转义。
  • 我不知道 Eclipse 配置正是我需要的!谢谢!
【解决方案2】:

我不明白 Java 不允许在代码中使用“多行”字符串这一事实有什么问题。您应该能够与其中包含 '\n' 和 '\t' 字符的字符串进行比较。这些“预期”字符串是在您的测试中硬编码还是来自输入文件是您的测试套件的设计决定。

【讨论】:

  • 我已经有了字符串。我无法将它们复制粘贴到问题代码中。顺便说一句,头像不错...
  • @Cratylus 查看我更新的答案,了解如何让这一切变得简单。说实话,我发现 Code-Guru 的图标对于这个论坛来说有点不合时宜(甚至可能令人反感)......但无论如何。
  • @Cratylus 你是什么意思你不能将字符串复制并粘贴到你的代码中?您的意思是由于某种原因不允许这样做,或者当您尝试时会发生意外情况?
  • Adam Gent 提到了粘贴时我不知道的 Eclipse 配置。您的回答似乎启发了他。来自我的 +1。
【解决方案3】:

我会支持@Adam Gent 的建议,添加一些示例代码以将资源读入字符串:

final InputStream is = StringFromFile.class.getResourceAsStream("data.txt");
final byte[] b = new byte[is.available()];
is.read(b);
System.out.println(new String(b, "UTF-8"));

您可以嵌入格式占位符(例如 %s、%d 等),然后使用 String.format 将它们替换为实际值。

如果你想拥有一个包含所有字符串的文件,你可以维护一个 xml 文件:

<strings>
    <string name="error 1"><![CDATA[Multiline
error
message 1]]></string>
    <string name="error 2"><![CDATA[Multiline
error
message 2]]></string>
    <string name="error 3"><![CDATA[Multiline
error
message 3]]></string>
</strings>

并将其导入地图 - 这样您就可以使用 map.get(name); 调用它

你可以找到类似here的例子

【讨论】:

  • 他也可以看看我的要点,它使用番石榴来完成上述工作。但感谢您的备份:)
  • 当然——我只是倾向于避免使用外部 jar 来完成简单的任务,除非你当然使用了多个重要的功能
  • 所以您建议为每个字符串创建一个单独的文件?为什么这种方法比使用单个文件更好?
猜你喜欢
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多