diff options
Diffstat (limited to 'src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java')
-rw-r--r-- | src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java | 94 |
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(); } |