为Junit测试包装多行字符串

时间:2012-10-16 14:49:39

标签: java eclipse junit

要在JUnit测试中比较多行文本结果,我经常需要从文本表示中获取 使用多行文本初始化字符串的Java代码。

E.g。如果测试应检查包含以下内容的xml字符串:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer>
    <id>100</id>
    <name>John Doe</name>
    <orders>
        <Order>
            <address>100 main street, smalltown, pa</address>
            <orderid>1100</orderid>
        </Order>
        <Order>
            <address>5 broadway, ny, ny</address>
            <orderid>1200</orderid>
        </Order>
    </orders>
</Customer>

我想使用一个工具/生成器来获取上面的输入并获得以下结果:

String expected ="";
    expected+="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
expected+="<Customer>\n";
expected+="    <id>100</id>\n";
expected+="    <name>John Doe</name>\n";
expected+="    <orders>\n";
expected+="        <Order>\n";
expected+="            <address>100 main street, smalltown, pa</address>\n";
expected+="            <orderid>1100</orderid>\n";
expected+="        </Order>\n";
expected+="        <Order>\n";
expected+="            <address>5 broadway, ny, ny</address>\n";
expected+="            <orderid>1200</orderid>\n";
expected+="        </Order>\n";
expected+="    </orders>\n";
expected+="</Customer>\n";

和/或

    // Create test file
    java.io.PrintWriter srcWriter = new java.io.PrintWriter(new java.io.FileOutputStream(testFile));
    srcWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
    srcWriter.println("<Customer>\n");
    srcWriter.println("    <id>100</id>\n");
    srcWriter.println("    <name>John Doe</name>\n");
    srcWriter.println("    <orders>\n");
    srcWriter.println("        <Order>\n");
    srcWriter.println("            <address>100 main street, smalltown, pa</address>\n");
    srcWriter.println("            <orderid>1100</orderid>\n");
    srcWriter.println("        </Order>\n");
    srcWriter.println("        <Order>\n");
    srcWriter.println("            <address>5 broadway, ny, ny</address>\n");
    srcWriter.println("            <orderid>1200</orderid>\n");
    srcWriter.println("        </Order>\n");
    srcWriter.println("    </orders>\n");
    srcWriter.println("</Customer>\n");
    srcWriter.close();
    // PrintWriter never throws Exceptions, one must check the error state manually
    //
    if (srcWriter.checkError())
    {
        throw new IOException( "can not write " + testFile );
    }   

实现此目的的开发工具/ eclipse实用程序或插件是什么?

  • 从文件(在IDE或命令行中)获取多行输入文本
  • 转义引号和反斜杠
  • 转换为初始化字符串文字的Java代码和/或将在java代码中创建文件而无需额外的文件资源
  • 将结果输出到新文件和/或控制台,或直接输出到编辑器中以便在编译时使用

输出文件(如果有)不应随编译结果一起提供。在文件模式下,应该从java代码中的字符串文字重新创建输入文件的等效项。

4 个答案:

答案 0 :(得分:8)

假设您正在从其他来源复制多行文本,并且您正在使用Eclipse,它可以自动将您的文本转换为多行字符串文字。

在我的版本中,在Windows下启用它 - &gt;偏好 - &gt; Java - &gt;编辑 - &gt;打字 - &gt;粘贴到字符串文字时转义文本

然后输入

String expected = "

并复制一些文字,如

blah
blah
blah
blah
blah

然后粘贴你的字符串,Eclipse创建:

 String expected = "blah\n" + 
 "blah\n" + 
 "blah\n" + 
 "blah\n" + 
 "blah"

就我个人而言,如果Java拥有与Perl的HERE文档等效的多行,那我认为会很好。

答案 1 :(得分:1)

为什么不将XML存储在单独的文件中并使用Apache Commons将其读入String?

String fileName = "path/to/your/file";
String fileText = FileUtils.readFileToString(new File(fileName));

请参阅FileUtils - https://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html

答案 2 :(得分:0)

对我来说这看起来像是失败。基本上,您希望测试具有特定于操作系统的换行符的漂亮打印XML。

难道你不能简单地编写一些简单的访问者模式来交叉生成和预期的XML来验证一切是否符合预期?通过这种方式,您还可以避免使用无效的预期和生成的XML的问题。

另外,假设命名空间声明按顺序改变或属性按顺序改变:XML在语义上是等效的,但在语法上是不同的。应如何处理?这是一次失败的测试吗?在我看来,这是一个通行证。

答案 3 :(得分:0)

对于非eclipse用户,以下脚本解决方案可能会有所帮助:

#!/bin/bash
#
#   Copyright (C) 2012 BITPlan GmbH (http://www.bitplan.com)
# 
#   Author: Wolfgang Fahl
#
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.


#
# wrap code for use in JUnit Test cases
#
wrapJUnit() {
  file=$1
  mode=$2
  echo "wrapping $file with mode $mode"
  cat $file | gawk -v mode="$mode" '

# check mode and add header if mode is file
BEGIN {
  if (mode=="file") {
        print " // Create test file"
        print " java.io.PrintWriter srcWriter = new java.io.PrintWriter(new java.io.FileOutputStream(testFile));"
    }   
}
# work on each line
{
    line=$0
    # replace a single \ with \\
    gsub("\\","\\\\",line)
    # replace a quote with \ quote
    gsub("\"","\\\"",line)
    # output the modified line
    if (mode=="file") {
        print " srcWriter.println(\"" line "\\n\");"
    } else {
        if (more++) {
            print " expected+=\"" line "\\n\";" 
        } else {
            print " expected =\"" line "\\n\";" 
        }   
    }   
}

END {
  if (mode=="file") {
        print " srcWriter.close();"
        print " // PrintWriter never throws Exceptions, one must check the error state manually"
        print " //"
        print " if (srcWriter.checkError())"
        print " {"
        print "     throw new IOException( \"can not write \" + testFile );"
        print " }   "
    }
}

' > $1.wrap
cat $1.wrap
}

#
#
# show usage
# 
usage() {
    echo "usage: wrapcode inputfile [simple]"
    echo "  will take the text and prepare it for JUnit usage as a string";
    exit 1
}

#
# check number of command line parameters
#
if [ $# -lt 1 ]
then
  usage
fi

file=$1

if [ $# -lt 2 ]
then
  wrapJUnit $file file
else
  wrapJUnit $file string
fi