-
-
Save frant-hartm/3ecd13f3ee191b720766 to your computer and use it in GitHub Desktop.
JUnit rule to conditionally ignore test cases (see also http://www.codeaffine.com/2013/11/18/a-junit-rule-to-conditionally-ignore-tests/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************* | |
* Copyright (c) 2013,2014 Rüdiger Herrmann | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* <p/> | |
* Contributors: | |
* Rüdiger Herrmann - initial API and implementation | |
* Matt Morrissette - allow to use non-static inner IgnoreConditions | |
******************************************************************************/ | |
package com.example.junit; | |
import java.lang.annotation.ElementType; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
import java.lang.reflect.Modifier; | |
import org.junit.Assume; | |
import org.junit.rules.MethodRule; | |
import org.junit.runners.model.FrameworkMethod; | |
import org.junit.runners.model.Statement; | |
public class ConditionalSupportRule implements MethodRule { | |
public interface RunCondition { | |
boolean isSatisfied(); | |
} | |
@Retention(RetentionPolicy.RUNTIME) | |
@Target({ElementType.METHOD}) | |
public @interface ConditionalSupport { | |
Class<? extends RunCondition> condition(); | |
} | |
@Override | |
public Statement apply(Statement base, FrameworkMethod method, Object target) { | |
Statement result = base; | |
if (hasConditionalIgnoreAnnotation(method)) { | |
RunCondition condition = getIgnoreContition(target, method); | |
if (!condition.isSatisfied()) { | |
result = new IgnoreStatement(condition); | |
} | |
} | |
return result; | |
} | |
private static boolean hasConditionalIgnoreAnnotation(FrameworkMethod method) { | |
return method.getAnnotation(ConditionalSupport.class) != null; | |
} | |
private static RunCondition getIgnoreContition(Object target, FrameworkMethod method) { | |
ConditionalSupport annotation = method.getAnnotation(ConditionalSupport.class); | |
return new IgnoreConditionCreator(target, annotation).create(); | |
} | |
private static class IgnoreConditionCreator { | |
private final Object target; | |
private final Class<? extends RunCondition> conditionType; | |
IgnoreConditionCreator(Object target, ConditionalSupport annotation) { | |
this.target = target; | |
this.conditionType = annotation.condition(); | |
} | |
RunCondition create() { | |
checkConditionType(); | |
try { | |
return createCondition(); | |
} catch (RuntimeException re) { | |
throw re; | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private RunCondition createCondition() throws Exception { | |
RunCondition result; | |
if (isConditionTypeStandalone()) { | |
result = conditionType.newInstance(); | |
} else { | |
result = conditionType.getDeclaredConstructor(conditionType.getDeclaringClass()).newInstance(target); | |
} | |
return result; | |
} | |
private void checkConditionType() { | |
if (!isConditionTypeStandalone() && !isConditionTypeDeclaredInTarget()) { | |
String msg | |
= "Conditional class '%s' is a member class " | |
+ "but was not declared inside the test case using it.\n" | |
+ "Either make this class a static class, " | |
+ "standalone class (by declaring it in it's own file) " | |
+ "or move it inside the test case using it"; | |
throw new IllegalArgumentException(String.format(msg, conditionType.getName())); | |
} | |
} | |
private boolean isConditionTypeStandalone() { | |
return !conditionType.isMemberClass() || Modifier.isStatic(conditionType.getModifiers()); | |
} | |
private boolean isConditionTypeDeclaredInTarget() { | |
// return target.getClass().isAssignableFrom(conditionType.getDeclaringClass()); | |
return true; | |
} | |
} | |
private static class IgnoreStatement extends Statement { | |
private final RunCondition condition; | |
IgnoreStatement(RunCondition condition) { | |
this.condition = condition; | |
} | |
@Override | |
public void evaluate() { | |
Assume.assumeTrue("Ignored by " + condition.getClass().getSimpleName(), false); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment