Skip to content

Commit

Permalink
Provide helpful message if parameter cannot be set.
Browse files Browse the repository at this point in the history
For private @parameter fields is users get an exception like
"java.lang.IllegalAccessException: Class ... can not access a member
of class X with modifiers private" The new message "Cannot set
parameter 'parameter'. Ensure that the the field 'parameter' is
public." tells the user what they should do.

The reason for adding this feature is the Stackoverflow question
https://stackoverflow.com/questions/44522046/reflection-exception-in-parameterized-junit-test-using-array-parameter/44522988
  • Loading branch information
stefanbirkner committed Jun 23, 2017
1 parent 7111b96 commit 6324fde
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ private Object createTestUsingFieldInjection() throws Exception {
int index = annotation.value();
try {
field.set(testClassInstance, parameters[index]);
} catch (IllegalAccessException e) {
IllegalAccessException wrappedException = new IllegalAccessException(
"Cannot set parameter '" + field.getName()
+ "'. Ensure that the field '" + field.getName()
+ "' is public.");
wrappedException.initCause(e);
throw wrappedException;
} catch (IllegalArgumentException iare) {
throw new Exception(getTestClass().getName()
+ ": Trying to set " + field.getName()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
package org.junit.runners.parameterized;

import static java.util.Collections.emptyList;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.rules.ExpectedException.none;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collections;
import java.util.List;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.model.TestClass;

public class BlockJUnit4ClassRunnerWithParametersTest {
private static final List<Object> NO_PARAMETERS = emptyList();

@Rule
public final ExpectedException thrown = none();

@RunWith(Parameterized.class)
@DummyAnnotation
public static class ClassWithParameterizedAnnotation {
Expand All @@ -42,4 +50,31 @@ public void hasAllAnnotationsExceptRunWith() throws Exception {
@Target(ElementType.TYPE)
private static @interface DummyAnnotation {
}

@RunWith(Parameterized.class)
public static class ClassWithPrivateParameter {
@Parameterized.Parameter
private String parameter;

@Test
public void dummyTest() {
}
}

@Test
public void providesHelpfulMessageIfParameterFieldCannotBeSet()
throws Exception {
TestWithParameters testWithParameters = new TestWithParameters(
"dummy name",
new TestClass(ClassWithPrivateParameter.class),
Collections.<Object>singletonList("dummy parameter"));
BlockJUnit4ClassRunnerWithParameters runner = new BlockJUnit4ClassRunnerWithParameters(
testWithParameters);

thrown.expect(IllegalAccessException.class);
thrown.expectCause(instanceOf(IllegalAccessException.class));
thrown.expectMessage("Cannot set parameter 'parameter'. Ensure that the field 'parameter' is public.");

runner.createTest();
}
}

0 comments on commit 6324fde

Please sign in to comment.