package org.junit.internal.runners;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
public abstract class BeforeAndAfterRunner {
private static class FailedBefore extends Exception {
private static final long serialVersionUID= 1L;
}
private final Class<? extends Annotation> fBeforeAnnotation;
private final Class<? extends Annotation> fAfterAnnotation;
private TestIntrospector fTestIntrospector;
private Object fTest;
public BeforeAndAfterRunner(Class<?> testClass,
Class<? extends Annotation> beforeAnnotation,
Class<? extends Annotation> afterAnnotation,
Object test) {
fBeforeAnnotation= beforeAnnotation;
fAfterAnnotation= afterAnnotation;
fTestIntrospector= new TestIntrospector(testClass);
fTest= test;
}
public void runProtected() {
try {
runBefores();
runUnprotected();
} catch (FailedBefore e) {
} finally {
runAfters();
}
}
protected abstract void runUnprotected();
protected abstract void addFailure(Throwable targetException);
// Stop after first failed @Before
private void runBefores() throws FailedBefore {
try {
List<Method> befores= fTestIntrospector.getTestMethods(fBeforeAnnotation);
for (Method before : befores)
invokeMethod(before);
} catch (InvocationTargetException e) {
addFailure(e.getTargetException());
throw new FailedBefore();
} catch (Throwable e) {
addFailure(e);
throw new FailedBefore();
}
}
// Try to run all @Afters regardless
private void runAfters() {
List<Method> afters= fTestIntrospector.getTestMethods(fAfterAnnotation);
for (Method after : afters)
try {
invokeMethod(after);
} catch (InvocationTargetException e) {
addFailure(e.getTargetException());
} catch (Throwable e) {
addFailure(e); // Untested, but seems impossible
}
}
private void invokeMethod(Method method) throws Exception {
method.invoke(fTest);
}
}