Skip to content

Commit

Permalink
Ensure exceptions from methodBlock() don't result in unrooted tests
Browse files Browse the repository at this point in the history
The introduction of the runLeaf() method in BlockJUnit4ClassRunner in
JUnit 4.9 introduced a regression with regard to exception handling.

Specifically, the invocation of methodBlock() is no longer executed
within a try-catch block as was the case in previous versions of JUnit.

Custom modifications to methodBlock() or the methods it invokes may in
fact throw exceptions. In such cases, exceptions thrown from
methodBlock() cause the current test execution to abort immediately. As
a result, the failing test method is unrooted in test reports, and
subsequent test methods are never invoked. Furthermore, RunListeners
registered with JUnit are not notified.

This commit addresses this issue by wrapping the invocation of
methodBlock() within a try-catch block. If an exception is not thrown,
the resulting Statement is passed to runLeaf(). If an exception is
thrown, it is wrapped in a Fail statement which is passed to runLeaf().

Issue: #1066
  • Loading branch information
sbrannen committed Feb 15, 2015
1 parent 0f0152a commit 69a77bd
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
* @since 4.5
*/
public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> {

private final ConcurrentHashMap<FrameworkMethod, Description> methodDescriptions = new ConcurrentHashMap<FrameworkMethod, Description>();

/**
* Creates a BlockJUnit4ClassRunner to run {@code testClass}
*
Expand All @@ -75,10 +77,17 @@ protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
if (isIgnored(method)) {
notifier.fireTestIgnored(description);
} else {
runLeaf(methodBlock(method), description, notifier);
Statement statement;
try {
statement = methodBlock(method);
}
catch (Throwable ex) {
statement = new Fail(ex);
}
runLeaf(statement, description, notifier);
}
}

/**
* Evaluates whether {@link FrameworkMethod}s are ignored based on the
* {@link Ignore} annotation.
Expand Down Expand Up @@ -390,10 +399,10 @@ private List<org.junit.rules.MethodRule> getMethodRules(Object target) {
protected List<MethodRule> rules(Object target) {
List<MethodRule> rules = getTestClass().getAnnotatedMethodValues(target,
Rule.class, MethodRule.class);

rules.addAll(getTestClass().getAnnotatedFieldValues(target,
Rule.class, MethodRule.class));

return rules;
}

Expand Down

0 comments on commit 69a77bd

Please sign in to comment.