首先,我知道标题有点含糊不清。其实我不知道怎么写得更好!
其次,我将描述问题。
我正在网上裁判(OJ)练习,所以在输出错误的情况下,OJ向我展示了使我的代码失败的测试用例。通常,我可以复制我的代码并将其粘贴到Eclipse中,然后使用该测试用例调用我的函数并调试我的代码。
但是当测试用例是多次调用我的函数(就像测试优先级队列的增强版本)时的问题,我们假设在代码失败之前有n次调用。所以要调试代码,我必须调用函数说n次!哪个不符合逻辑!
OJ将调用的函数:
public void enqueue (int value)
{
// implementation
}
public int dequeue ()
{
// implementation
}
测试用例使代码失败:
Last executed input: enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16),... dequeue(),...
我需要一种方法来调用带有测试用例数组的函数,以便能够调试代码。
OR
通过某种方式直接从字符串中调用函数及其参数。像invoke("enqueue(5, 3)");
答案 0 :(得分:1)
经过一些调查后,我找到了一种方法,可以使用Java Reflection来完成我需要的操作。这也是一个有用的帖子What is reflection and why is it useful?
我设法开发了一个工具,这里是你的步骤:
我使用了Reflection,以便能够在for循环中从一串调用中调用方法。
然后我们有了这个
public class Test
{
public static void main(String[] args)
{
String testCase = "enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16), dequeue()";
// Prepare parameters and invocations
int[] param1; // assuming it is ready
int[] param2; // assuming it is ready
String[] calls; // assuming it is ready
try
{
Class calledClass = Class.forName("OJ.Prob3");
Method calledMethod1 = calledClass.getDeclaredMethod("enqueue", String.class, int.class);
Method calledMethod2 = calledClass.getDeclaredMethod("dequeue", null);
for (int i = 0 ; i < calls.length ; i++)
{
if (calls[i].equalsIgnoreCase("enqueue"))
calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]);
else if (calls[i].equalsIgnoreCase("dequeue"))
calledMethod2.invoke(calledClass.newInstance())
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
}
我已经测试了这个解决方案,它的工作非常顺利,但是如果有人有更好的解决方案,那么欢迎你。
我将最终确定代码并使其成为一种工具,我会尽快发布,以便让每个人的生活更轻松地调试在线评审测试用例。
<强>更新强>
您可以对静态方法执行相同操作,只需将.newInstance()
从calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]);
移除到calledMethod1.invoke(calledClass, param[i], param2[i]);