@@ -433,18 +433,51 @@ INFO: Method [sleep50ms] took 53 ms.
433433[[extensions-exception-handling]]
434434=== Exception Handling
435435
436- `{TestExecutionExceptionHandler}` defines the API for `Extensions` that wish to handle
437- exceptions thrown during test execution.
436+ Exceptions thrown during the test execution may be intercepted and handled accordingly
437+ before propagating further, so that certain actions like error logging or resource releasing
438+ may be defined in specialized `Extensions`. JUnit Jupiter offers API for `Extensions` that
439+ wish to handle exceptions thrown during `@Test` methods via `{TestExecutionExceptionHandler}`
440+ and for those thrown during one of test lifecycle methods (`@BeforeAll`, `@BeforeEach`,
441+ `@AfterEach` and `@AfterAll`) via `{LifecycleMethodExecutionExceptionHandler}`.
438442
439443The following example shows an extension which will swallow all instances of `IOException`
440444but rethrow any other type of exception.
441445
442446[source,java,indent=0]
443- .An exception handling extension
447+ .An exception handling extension that filters IOExceptions in test execution
444448----
445449include::{testDir}/example/exception/IgnoreIOExceptionExtension.java[tags=user_guide]
446450----
447451
452+ Another example shows how to record the state of an application under test exactly at
453+ the point of unexpected exception being thrown during setup and cleanup. Note that unlike
454+ relying on lifecycle callbacks, which may or may not be executed depending on the test
455+ status, this solution guarantees execution immediately after failing `@BeforeAll`,
456+ `@BeforeEach`, `@AfterEach` or `@AfterAll`.
457+
458+ [source,java,indent=0]
459+ .An exception handling extension that records application state on error
460+ ----
461+ include::{testDir}/example/exception/RecordStateOnErrorExtension.java[tags=user_guide]
462+ ----
463+
464+ Multiple execution exception handlers may be invoked for the same lifecycle method in
465+ order of declaration. If one of the handlers swallows the handled exception, subsequent
466+ ones will not be executed, and no failure will be propagated to JUnit engine, as if the
467+ exception was never thrown. Handlers may also choose to rethrow the exception or throw
468+ a different one, potentially wrapping the original.
469+
470+ Extensions implementing `{LifecycleMethodExecutionExceptionHandler}` that wish to handle
471+ exceptions thrown during `@BeforeAll` or `@AfterAll` need to be registered on a class level,
472+ while handlers for `BeforeEach` and `AfterEach` may be also registered for individual
473+ test methods.
474+
475+ [source,java,indent=0]
476+ .An exception handling extension that records application state on error
477+ ----
478+ include::{testDir}/example/exception/MultipleHandlersTestCase.java[tags=user_guide]
479+ ----
480+
448481[[extensions-intercepting-invocations]]
449482=== Intercepting Invocations
450483
@@ -584,7 +617,7 @@ test method and will be repeated for every test method in the test class.
584617[#extensions-execution-order-diagram,reftext='{figure-caption}']
585618image::extensions_lifecycle.png[caption='',title='{figure-caption}']
586619
587- The following table further explains the twelve steps in the
620+ The following table further explains the sixteen steps in the
588621<<extensions-execution-order-diagram>> diagram.
589622
590623[cols="5,15,80"]
@@ -600,48 +633,68 @@ The following table further explains the twelve steps in the
600633| user code executed before all tests of the container are executed
601634
602635| 3
636+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler
637+ #handleBeforeAllMethodExecutionException`
638+ | extension code for handling exceptions thrown during a method annotated with `@BeforeAll`
639+
640+ | 4
603641| interface `org.junit.jupiter.api.extension.BeforeEachCallback`
604642| extension code executed before each test is executed
605643
606- | 4
644+ | 5
607645| annotation `org.junit.jupiter.api.BeforeEach`
608646| user code executed before each test is executed
609647
610- | 5
648+ | 6
649+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler
650+ #handleBeforeEachMethodExecutionException`
651+ | extension code for handling exceptions thrown during a method annotated with `@BeforeEach`
652+
653+ | 7
611654| interface `org.junit.jupiter.api.extension.BeforeTestExecutionCallback`
612655| extension code executed immediately before a test is executed
613656
614- | 6
657+ | 8
615658| annotation `org.junit.jupiter.api.Test`
616659| user code of the actual test method
617660
618- | 7
661+ | 9
619662| interface `org.junit.jupiter.api.extension.TestExecutionExceptionHandler`
620663| extension code for handling exceptions thrown during a test
621664
622- | 8
665+ | 10
623666| interface `org.junit.jupiter.api.extension.AfterTestExecutionCallback`
624667| extension code executed immediately after test execution and its corresponding exception handlers
625668
626- | 9
669+ | 11
627670| annotation `org.junit.jupiter.api.AfterEach`
628671| user code executed after each test is executed
629672
630- | 10
673+ | 12
674+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler
675+ #handleAfterEachMethodExecutionException`
676+ | extension code for handling exceptions thrown during a method annotated with `@AfterEach`
677+
678+ | 13
631679| interface `org.junit.jupiter.api.extension.AfterEachCallback`
632680| extension code executed after each test is executed
633681
634- | 11
682+ | 14
635683| annotation `org.junit.jupiter.api.AfterAll`
636684| user code executed after all tests of the container are executed
637685
638- | 12
686+ | 15
687+ | interface `org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler
688+ #handleAfterAllMethodExecutionException`
689+ | extension code for handling exceptions thrown during a method annotated with `@AfterAll`
690+
691+ | 16
639692| interface `org.junit.jupiter.api.extension.AfterAllCallback`
640693| extension code executed after all tests of the container are executed
641694
642695|===
643696
644- In the simplest case only the actual test method will be executed (step 6 ); all other
697+ In the simplest case only the actual test method will be executed (step 8 ); all other
645698steps are optional depending on the presence of user code or extension support for the
646699corresponding lifecycle callback. For further details on the various lifecycle callbacks
647700please consult the respective Javadoc for each annotation and extension.
0 commit comments