5

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

例如,如果测试应该检查包含以下内容的 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

4 回答 4

8

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

在我的版本中,在 Windows -> Preferences -> Java -> Editor -> Typing -> Escape text when paste into a String literal 下启用它

然后如果你输入

String expected = "

并复制一些文字,例如

blah
blah
blah
blah
blah

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

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

我个人认为如果 Java 有一个与 Perl 的 HERE 文档等效的多行文档会很好。

于 2012-10-16T15:16:13.877 回答
1

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

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

于 2012-10-16T15:22:02.653 回答
0

在我看来,这似乎是一个失败。基本上,您想针对带有操作系统特定换行符的漂亮打印的 XML 进行测试。

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

此外,想象一下命名空间声明是否按顺序更改或属性按顺序更改:XML 在语义上是等价的,但在语法上是不同的。这个应该怎么处理?这是一次失败的测试吗?在我看来,这是通行证。

于 2012-10-16T15:40:35.333 回答
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
于 2012-10-17T07:31:24.657 回答