package org.powermock.modules.junit4.internal.impl; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.internal.runners.InitializationError; import org.junit.internal.runners.TestMethod; import org.junit.rules.MethodRule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.Statement; import org.powermock.core.spi.PowerMockTestListener; /** * Extends the functionality of {@link PowerMockJUnit47RunnerDelegateImpl} to enable the usage of * {@link TestRule}. */ @SuppressWarnings( "deprecation" ) public class PowerMockJUnit49RunnerDelegateImpl extends PowerMockJUnit47RunnerDelegateImpl { public PowerMockJUnit49RunnerDelegateImpl( Class<?> klass, String[] methodsToRun, PowerMockTestListener[] listeners ) throws InitializationError { super( klass, methodsToRun, listeners ); } public PowerMockJUnit49RunnerDelegateImpl( Class<?> klass, String[] methodsToRun ) throws InitializationError { super( klass, methodsToRun ); } public PowerMockJUnit49RunnerDelegateImpl( Class<?> klass ) throws InitializationError { super( klass ); } @Override protected PowerMockJUnit47MethodRunner createPowerMockRunner( final Object testInstance, final TestMethod testMethod, RunNotifier notifier, Description description, final boolean extendsFromTestCase ) { return new PowerMockJUnit49MethodRunner( testInstance, testMethod, notifier, description, extendsFromTestCase ); } protected class PowerMockJUnit49MethodRunner extends PowerMockJUnit47MethodRunner { private Description description; protected PowerMockJUnit49MethodRunner( Object testInstance, TestMethod method, RunNotifier notifier, Description description, boolean extendsFromTestCase ) { super( testInstance, method, notifier, description, extendsFromTestCase ); this.description = description; } @Override protected Statement applyRuleToLastStatement(final Method method, final Object testInstance, Field field, final Statement lastStatement) throws IllegalAccessException { final Object fieldValue = field.get(testInstance); final Statement statement; if (fieldValue instanceof MethodRule) { // the MethodRule is known by junit 4.9 -> delegate to super-class statement = super.applyRuleToLastStatement(method, testInstance, field, lastStatement); } else if (fieldValue instanceof TestRule){ TestRule rule = (TestRule) fieldValue; statement = rule.apply(lastStatement, description); } else { throw new IllegalStateException("Can only handle MethodRule and TestRule"); } return statement; } } }