package org.junit.rules;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Rule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
The RuleChain
can be used for creating composite rules. You create a RuleChain
with outerRule(TestRule)
and subsequent calls of around(TestRule)
: public abstract class CompositeRules {
public static TestRule extendedLogging() {
return RuleChain.outerRule(new LoggingRule("outer rule"))
.around(new LoggingRule("middle rule"))
.around(new LoggingRule("inner rule"));
}
}
public class UseRuleChain {
@Rule
public final TestRule extendedLogging = CompositeRules.extendedLogging();
@Test
public void example() {
assertTrue(true);
}
}
writes the log
starting outer rule
starting middle rule
starting inner rule
finished inner rule
finished middle rule
finished outer rule
In older versions of JUnit (before 4.13) RuleChain
was used for ordering rules. We recommend to not use it for this purpose anymore. You can use the attribute order
of the annotation Rule
or ClassRule
for ordering rules. See Also: Since: 4.10
/**
* The {@code RuleChain} can be used for creating composite rules. You create a
* {@code RuleChain} with {@link #outerRule(TestRule)} and subsequent calls of
* {@link #around(TestRule)}:
*
* <pre>
* public abstract class CompositeRules {
* public static TestRule extendedLogging() {
* return RuleChain.outerRule(new LoggingRule("outer rule"))
* .around(new LoggingRule("middle rule"))
* .around(new LoggingRule("inner rule"));
* }
* }
* </pre>
*
* <pre>
* public class UseRuleChain {
* @Rule
* public final TestRule extendedLogging = CompositeRules.extendedLogging();
*
* @Test
* public void example() {
* assertTrue(true);
* }
* }
* </pre>
*
* writes the log
*
* <pre>
* starting outer rule
* starting middle rule
* starting inner rule
* finished inner rule
* finished middle rule
* finished outer rule
* </pre>
*
* In older versions of JUnit (before 4.13) {@code RuleChain} was used for
* ordering rules. We recommend to not use it for this purpose anymore. You can
* use the attribute {@code order} of the annotation {@link Rule#order() Rule}
* or {@link org.junit.ClassRule#order() ClassRule} for ordering rules.
*
* @see org.junit.Rule#order()
* @see org.junit.ClassRule#order()
* @since 4.10
*/
public class RuleChain implements TestRule {
private static final RuleChain EMPTY_CHAIN = new RuleChain(
Collections.<TestRule>emptyList());
private List<TestRule> rulesStartingWithInnerMost;
Returns: a RuleChain
without a TestRule
.
/**
* Returns a {@code RuleChain} without a {@link TestRule}. This method may
* be the starting point of a {@code RuleChain}.
*
* @return a {@code RuleChain} without a {@link TestRule}.
*/
public static RuleChain emptyRuleChain() {
return EMPTY_CHAIN;
}
Params: - outerRule – the outer rule of the
RuleChain
.
Returns: a RuleChain
with a single TestRule
.
/**
* Returns a {@code RuleChain} with a single {@link TestRule}. This method
* is the usual starting point of a {@code RuleChain}.
*
* @param outerRule the outer rule of the {@code RuleChain}.
* @return a {@code RuleChain} with a single {@link TestRule}.
*/
public static RuleChain outerRule(TestRule outerRule) {
return emptyRuleChain().around(outerRule);
}
private RuleChain(List<TestRule> rules) {
this.rulesStartingWithInnerMost = rules;
}
Params: - enclosedRule – the rule to enclose; must not be
null
.
Throws: - NullPointerException – if the argument
enclosedRule
is null
Returns: a new RuleChain
.
/**
* Create a new {@code RuleChain}, which encloses the given {@link TestRule} with
* the rules of the current {@code RuleChain}.
*
* @param enclosedRule the rule to enclose; must not be {@code null}.
* @return a new {@code RuleChain}.
* @throws NullPointerException if the argument {@code enclosedRule} is {@code null}
*/
public RuleChain around(TestRule enclosedRule) {
if (enclosedRule == null) {
throw new NullPointerException("The enclosed rule must not be null");
}
List<TestRule> rulesOfNewChain = new ArrayList<TestRule>();
rulesOfNewChain.add(enclosedRule);
rulesOfNewChain.addAll(rulesStartingWithInnerMost);
return new RuleChain(rulesOfNewChain);
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public Statement apply(Statement base, Description description) {
return new RunRules(base, rulesStartingWithInnerMost, description);
}
}