我正在测试我的应用程序的一部分(我们假设是一个名为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()
?
答案 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的语法。