1

I tried to setup a parameterized test in JUnit 4.11 which generates a single parameter. This parameter, however, needs to be an array itself.

The expected behavior for the following code snippet would be that test() is run twice while arguments holds an array {"test1", "test2"} in the first run and an array {"test3", "test4"} in the second run.

@RunWith(Parameterized.class)
public class Tester {

    @Parameter
    private String[] arguments;

    @Parameters
    public static Iterable<Object[]> data() {
        return Arrays.asList(
                new Object[][]{
                    {new String[] {"test1","test2"}},
                    {new String[] {"test3","test4"}}
                }
        );  
    }

    @Test
    public void test() {
        fail();
    }
}

When I execute the test, however, a SlowCheckMemberAccess Exception is thrown. Google delivered no results for that kind of problem.

Can anyone explain what is going wrong here?

The unfiltered JUnit trace is:

java.lang.IllegalAccessException: Class org.junit.runners.Parameterized$TestClassRunnerForParameters can not access a member of class org.mafagafogigante.dungeon.entity.creatures.Tester with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.junit.runners.Parameterized$TestClassRunnerForParameters.createTestUsingFieldInjection(Parameterized.java:201)
at org.junit.runners.Parameterized$TestClassRunnerForParameters.createTest(Parameterized.java:179)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
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.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
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:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Johnson
  • 306
  • 1
  • 15
  • As always: Post the stacktrace! – Seelenvirtuose Jun 13 '17 at 12:53
  • 2
    Well ... "can not access a member of class org.mafagafogigante.dungeon.entity.creatures.HeroTest with modifiers _private_" ... Anything unclear? – Seelenvirtuose Jun 13 '17 at 13:10
  • 1
    Oh dear, I always had that "Filter Trace" activated in the Failure Trace few of Eclipse. That's where my confusion came from. Looking at the full trace now the mistake is obvious. Thank you for that broad hint. I edited the trace to correctly reflect the example. – Johnson Jun 13 '17 at 13:36

2 Answers2

6

The field that is annotated with @Parameter has to be public.

JUnit 4.13 will have an improved error message:

Cannot set parameter 'arguments'. Ensure that the field 'arguments' is public.
Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
-2

I do not think you need Arrays.asList() as arrays are Iterable, too.

Also Arrays.asList() can be fooled if you specify a single array argument to it. If you want to use it, add explicit cast.

Usagi Miyamoto
  • 6,196
  • 1
  • 19
  • 33
  • Arrays are not iterable in a sense that you can use them as implementation of the `Iterable` interface. Found a discussion here: https://stackoverflow.com/questions/1160081/why-is-an-array-not-assignable-to-iterable. The notation is taken directly from the JUnit website: https://github.com/junit-team/junit4/wiki/Parameterized-tests. – Johnson Jun 13 '17 at 13:23