Skip to content

Commit cf13399

Browse files
committed
Recommend to always set order for TestWatcher
TestWatcher may see failed tests as successful and vice versa if it is not the outermost rule and another rule changes the result of a test (e.g. ErrorCollector or ExpectedException). Fixes #1436.
1 parent 0bec573 commit cf13399

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/main/java/org/junit/rules/TestWatcher.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.List;
55

66
import org.junit.AssumptionViolatedException;
7+
import org.junit.Rule;
78
import org.junit.runner.Description;
89
import org.junit.runners.model.MultipleFailureException;
910
import org.junit.runners.model.Statement;
@@ -17,7 +18,7 @@
1718
* public static class WatchmanTest {
1819
* private static String watchedLog;
1920
*
20-
* @Rule
21+
* @Rule(order = Integer.MIN_VALUE)
2122
* public TestWatcher watchman= new TestWatcher() {
2223
* @Override
2324
* protected void failed(Throwable e, Description description) {
@@ -40,6 +41,11 @@
4041
* }
4142
* }
4243
* </pre>
44+
* <p>It is recommended to always set the {@link Rule#order() order} of the
45+
* {@code TestWatcher} to {@code Integer.MIN_VALUE} so that it encloses all
46+
* other rules. Otherwise it may see failed tests as successful and vice versa
47+
* if some rule changes the result of a test (e.g. {@link ErrorCollector} or
48+
* {@link ExpectedException}).
4349
*
4450
* @since 4.9
4551
*/

src/test/java/org/junit/rules/TestWatcherTest.java

+52
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import static org.junit.experimental.results.PrintableResult.testResult;
88
import static org.junit.experimental.results.ResultMatchers.failureCountIs;
99
import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
10+
import static org.junit.rules.ExpectedException.none;
1011

1112
import org.junit.Rule;
1213
import org.junit.Test;
@@ -342,4 +343,55 @@ public void finished() {
342343
Finished.catchedDescription.getDisplayName());
343344
}
344345
}
346+
347+
//The following tests check the information in TestWatcher's Javadoc
348+
//regarding interplay with other rules.
349+
public static class InterplayWithOtherRules {
350+
private static StringBuilder log;
351+
352+
public static class ExpectedExceptionTest {
353+
@Rule(order = Integer.MIN_VALUE)
354+
//the field name must be alphabetically lower than "thrown" in order
355+
//to make the test failing if order is not set
356+
public final TestRule a = new LoggingTestWatcher(log);
357+
358+
@Rule
359+
public final ExpectedException thrown = none();
360+
361+
@Test
362+
public void testWithExpectedException() {
363+
thrown.expect(RuntimeException.class);
364+
throw new RuntimeException("expected exception");
365+
}
366+
}
367+
368+
@Test
369+
public void expectedExceptionIsSeenAsSuccessfulTest() {
370+
log = new StringBuilder();
371+
JUnitCore.runClasses(ExpectedExceptionTest.class);
372+
assertEquals("starting succeeded finished ", log.toString());
373+
}
374+
375+
public static class ErrorCollectorTest {
376+
@Rule(order = Integer.MIN_VALUE)
377+
//the field name must be alphabetically lower than "collector" in
378+
//order to make the test failing if order is not set
379+
public final TestRule a = new LoggingTestWatcher(log);
380+
381+
@Rule
382+
public final ErrorCollector collector = new ErrorCollector();
383+
384+
@Test
385+
public void test() {
386+
collector.addError(new RuntimeException("expected exception"));
387+
}
388+
}
389+
390+
@Test
391+
public void testIsSeenAsFailedBecauseOfCollectedError() {
392+
log = new StringBuilder();
393+
JUnitCore.runClasses(ErrorCollectorTest.class);
394+
assertEquals("starting failed finished ", log.toString());
395+
}
396+
}
345397
}

0 commit comments

Comments
 (0)