输出是文本墙时的单元测试

时间:2011-10-10 11:02:29

标签: java unit-testing testing

我正在测试我的应用程序的一部分(我们假设是一个名为X的类),它将参数作为反射java方法,并将基于它打印一些java代码(即,它是一个代码生成器)。例如,将String.toString()传递给X时,渲染的字符串输出将为:

public static java.lang.String toString(String thisObj, boolean isMonitoring) {
    String thisObjOld = (String)thisObj.clone(thisObj, false);

    if (isMonitoring) {
        toStringPre(thisObj);
    }

    java.lang.String result = thisObj.toString_Original();

    if (isMonitoring) {
        toStringPost(thisObj, thisObjOld, result);
    }

    return result
}

现在,我想知道如何测试此输出。我想测试不同的东西(单独)。

我知道完美的事情就是在打印之前对抽象表示进行断言,而不是最终文本。但不幸的是,似乎只需要设置太多工作。

我想要测试的事情的例子是:

  • 如果返回类型正确(java.lang.String);
  • 如果方法的名称是正确的(toString),以及它的参数`(String thisObj,boolean isMonitoring)。

如何更好地接近这个?使用正则表达式?使用String.split()

3 个答案:

答案 0 :(得分:2)

编译生成代码怎么样 - 测试代码语法是否正确。

然后使用Reflection检查名称,参数和返回类型。

然后在Mocked环境中运行它以检查它是否应该执行它应该做的事情。

答案 1 :(得分:1)

我认为如果生成的代码非常具有确定性(并且从查看你的问题, 看起来是确定性的),那么我首先要从X中手写正确的字符串输出,并做一个字符串比较。

例如,一个junit例子:

public void testX(){
   X gnerator = new X(getTestMethodObject());
   Assert.assertEquals(StringUtils.readFully(new File("expected_output.txt")), generator.generate());
}

显然,这将执行字符串比较,当生成的内容发生变化时,您必须手动编写新的预期输出。因此,虽然这很简单,但可能后来成为维护噩梦。

另一方面,当然是将生成的输出放在一边并检查生成的标记(我假设您无法在测试环境中实际编译生成的代码)。说,http://code.google.com/p/java-lexer/这是一个非常简单的词素(我不担保它 - 我只是在几分钟的谷歌搜索中找到它......但它有some basic tests,所以我认为它很好?) 。或者,使用更多的complex like antlr,这可能是一种过度的测试。

我个人会坚持将手写的预期输出与生成的输出进行比较。它的关键度要低得多,而且比使用全面的词法更容易发现错误。

答案 2 :(得分:0)

为什么不1)编译生成的代码并使用反射来断言“语义”,或者,如果由于依赖性和内容而无法进行编译和加载,2)使用JAVA解析器创建抽象语法您可以遍历并进行断言的树。 (例如,ANTLR项目具有JAVA 6的语法。