First, I know the Title is a bit ambiguous. Actually I don't know how to write it better!
Second, I will describe the problem.
I am practicing on an online judge (OJ), so in case of wrong output, the OJ shows me the test case which makes my code to fail. Normally, I can copy my code and paste it into Eclipse, then call my function with that test case and debug my code.
But the problem when the test case is a multiple calls for my function (Like testing an enhanced version of a priority queue), let's assume there were n calls till the fail of the code. So to debug the code, I will have to call the function say n times! Which is not logical!
Function the OJ will call:
public void enqueue (int value)
{
// implementation
}
public int dequeue ()
{
// implementation
}
Test case makes the code to fail:
Last executed input: enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16),... dequeue(),...
I need a way to call the function with an array of test cases in order to be able to debug the code.
OR
By some way call the function with its parameter directly from the string. Something like invoke("enqueue(5, 3)");
After some investigation, I found a way to do the Action I need by using Java Reflection Also a helpful thread What is reflection and why is it useful?
I managed to develop a tool, here you are the steps:
I used Reflection in order to be able to call the methods from a string of calls, inside a for loop.
Then we have this
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();
}
}
}
I already tested this solution and it works really very smooth, but please if anyone has a better solution, you will be more than welcome.
I will finalize the code and make it something like a tool, and I will post it soon, in order to make everybody's life easier debugging the online judges test cases.
Update:
You can do the same for the static methods, just remove .newInstance() from calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]); to something like calledMethod1.invoke(calledClass, param[i], param2[i]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With