aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java')
-rw-r--r--src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java94
1 files changed, 85 insertions, 9 deletions
diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
index 1c49f84..5c70a75 100644
--- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
+++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
@@ -4,8 +4,12 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
+import org.junit.internal.runners.statements.RunAfters;
+import org.junit.internal.runners.statements.RunBefores;
+import org.junit.runner.RunWith;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.model.FrameworkField;
import org.junit.runners.model.FrameworkMethod;
@@ -18,13 +22,17 @@ import org.junit.runners.model.Statement;
*/
public class BlockJUnit4ClassRunnerWithParameters extends
BlockJUnit4ClassRunner {
+ private enum InjectionType {
+ CONSTRUCTOR, FIELD
+ }
+
private final Object[] parameters;
private final String name;
public BlockJUnit4ClassRunnerWithParameters(TestWithParameters test)
throws InitializationError {
- super(test.getTestClass().getJavaClass());
+ super(test.getTestClass());
parameters = test.getParameters().toArray(
new Object[test.getParameters().size()]);
name = test.getName();
@@ -32,10 +40,15 @@ public class BlockJUnit4ClassRunnerWithParameters extends
@Override
public Object createTest() throws Exception {
- if (fieldsAreAnnotated()) {
- return createTestUsingFieldInjection();
- } else {
- return createTestUsingConstructorInjection();
+ InjectionType injectionType = getInjectionType();
+ switch (injectionType) {
+ case CONSTRUCTOR:
+ return createTestUsingConstructorInjection();
+ case FIELD:
+ return createTestUsingFieldInjection();
+ default:
+ throw new IllegalStateException("The injection type "
+ + injectionType + " is not supported.");
}
}
@@ -60,6 +73,13 @@ public class BlockJUnit4ClassRunnerWithParameters extends
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()
@@ -86,7 +106,7 @@ public class BlockJUnit4ClassRunnerWithParameters extends
@Override
protected void validateConstructor(List<Throwable> errors) {
validateOnlyOneConstructor(errors);
- if (fieldsAreAnnotated()) {
+ if (getInjectionType() != InjectionType.CONSTRUCTOR) {
validateZeroArgConstructor(errors);
}
}
@@ -94,7 +114,7 @@ public class BlockJUnit4ClassRunnerWithParameters extends
@Override
protected void validateFields(List<Throwable> errors) {
super.validateFields(errors);
- if (fieldsAreAnnotated()) {
+ if (getInjectionType() == InjectionType.FIELD) {
List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
int[] usedIndices = new int[annotatedFieldsByParameter.size()];
for (FrameworkField each : annotatedFieldsByParameter) {
@@ -125,18 +145,74 @@ public class BlockJUnit4ClassRunnerWithParameters extends
@Override
protected Statement classBlock(RunNotifier notifier) {
- return childrenInvoker(notifier);
+ Statement statement = childrenInvoker(notifier);
+ statement = withBeforeParams(statement);
+ statement = withAfterParams(statement);
+ return statement;
+ }
+
+ private Statement withBeforeParams(Statement statement) {
+ List<FrameworkMethod> befores = getTestClass()
+ .getAnnotatedMethods(Parameterized.BeforeParam.class);
+ return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores);
+ }
+
+ private class RunBeforeParams extends RunBefores {
+ RunBeforeParams(Statement next, List<FrameworkMethod> befores) {
+ super(next, befores, null);
+ }
+
+ @Override
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ int paramCount = method.getMethod().getParameterTypes().length;
+ method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters);
+ }
+ }
+
+ private Statement withAfterParams(Statement statement) {
+ List<FrameworkMethod> afters = getTestClass()
+ .getAnnotatedMethods(Parameterized.AfterParam.class);
+ return afters.isEmpty() ? statement : new RunAfterParams(statement, afters);
+ }
+
+ private class RunAfterParams extends RunAfters {
+ RunAfterParams(Statement next, List<FrameworkMethod> afters) {
+ super(next, afters, null);
+ }
+
+ @Override
+ protected void invokeMethod(FrameworkMethod method) throws Throwable {
+ int paramCount = method.getMethod().getParameterTypes().length;
+ method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters);
+ }
}
@Override
protected Annotation[] getRunnerAnnotations() {
- return new Annotation[0];
+ Annotation[] allAnnotations = super.getRunnerAnnotations();
+ Annotation[] annotationsWithoutRunWith = new Annotation[allAnnotations.length - 1];
+ int i = 0;
+ for (Annotation annotation: allAnnotations) {
+ if (!annotation.annotationType().equals(RunWith.class)) {
+ annotationsWithoutRunWith[i] = annotation;
+ ++i;
+ }
+ }
+ return annotationsWithoutRunWith;
}
private List<FrameworkField> getAnnotatedFieldsByParameter() {
return getTestClass().getAnnotatedFields(Parameter.class);
}
+ private InjectionType getInjectionType() {
+ if (fieldsAreAnnotated()) {
+ return InjectionType.FIELD;
+ } else {
+ return InjectionType.CONSTRUCTOR;
+ }
+ }
+
private boolean fieldsAreAnnotated() {
return !getAnnotatedFieldsByParameter().isEmpty();
}