Pragmatists/JUnitParams

Better exception for missing parameters

Closed this issue · 5 comments

If you have a test case with too few parameters specified, the method InvokeParameterisedMethod.createArrayOfTypesOf throws a NullPointerException, rather than something more informative to say "the 3rd test case has too few parameters". Could it be made more informative like that?

I'm not sure how general this is, but the case I'm working on was using a parameters method that returns an Object[][].

I spent a while chasing this, before I figured out I'd missed a parameter on one line. (I considered installing JUnitParams source to track the NPE, and I also started disabling tests one by one, because the error happens before a test starts, so it doesn't indicate which one caused the problem.)

java.lang.NullPointerException
at junitparams.internal.InvokeParameterisedMethod.createArrayOfTypesOf(InvokeParameterisedMethod.java:94)
at junitparams.internal.InvokeParameterisedMethod.castParamsFromObjects(InvokeParameterisedMethod.java:66)
at junitparams.internal.InvokeParameterisedMethod.(InvokeParameterisedMethod.java:38)
at junitparams.internal.ParameterisedTestClassRunner.buildMethodInvoker(ParameterisedTestClassRunner.java:124)
at junitparams.internal.ParameterisedTestClassRunner.parameterisedMethodInvoker(ParameterisedTestClassRunner.java:118)
at junitparams.JUnitParamsRunner.methodInvoker(JUnitParamsRunner.java:448)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:251)
at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:417)
at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:386)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

I cannot reproduce this:

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.assertj.core.api.Assertions.*;

@RunWith(JUnitParamsRunner.class)
public class GH155Test {

    @Test
    @Parameters(method = "gh155Params")
    public void gh155(String a, String b) {
        assertThat(a).isEqualTo(b);
    }

    public Object[][] gh155Params() {
        return new Object[][]{
                new Object[]{"pass", "pass"},
                new Object[]{"fail"}
        };
    }
}

First case passes, second case fails with:

java.lang.IllegalArgumentException: wrong number of arguments
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at junitparams.internal.InvokeParameterisedMethod.evaluate(InvokeParameterisedMethod.java:234)
	at junitparams.internal.ParameterisedTestMethodRunner.runMethodInvoker(ParameterisedTestMethodRunner.java:47)
	at junitparams.internal.ParameterisedTestMethodRunner.runTestMethod(ParameterisedTestMethodRunner.java:40)
	at junitparams.internal.ParameterisedTestClassRunner.runParameterisedTest(ParameterisedTestClassRunner.java:146)
	at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:446)
	at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:393)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Checked with JUnitParams 1.1.0 and 1.1.1

I'll try to look at it some more. I see the same as you for your example.

Ok, I've tracked it down. I don't know the official policy on nulls in argument arrays, but JUParams does work with nulls if I don't get the number of arguments wrong. However, in some cases, if the number of arguments is wrong, a null in the list causes the NPE in the method noted in my stack, because the null paramset[i] triggers an NPE in paramset[i].getClass();

In your example, try:
public Object[][] gh155Params() {
return new Object[][]{
new Object[]{null},
};
}

My own case is complicated (11 parameters, a couple of which were null, and removing one parameter causes the exception.)

Note, the exception happens in class setup, not during the test.

(I deleted a comment about Eclipse that was due to an incompatible version of junit.)

Thanks for reporting this.

Issue with missing null params is fixed.

@adammichalik thanks for test case.I have also updated IllegalArgumentException message to say:

Number of parameters in data provider method doesn't match the number of test method parameters. Number of parameters in provider method is 1, while the number of parameters in the gh155 test is 2