Class SoftlyExtension

  • All Implemented Interfaces:
    org.junit.jupiter.api.extension.AfterTestExecutionCallback, org.junit.jupiter.api.extension.Extension, org.junit.jupiter.api.extension.TestInstancePostProcessor

    public class SoftlyExtension
    extends Object
    implements org.junit.jupiter.api.extension.AfterTestExecutionCallback, org.junit.jupiter.api.extension.TestInstancePostProcessor
    Extension for JUnit Jupiter that provides support for injecting an instance of SoftAssertions into a class test SoftAssertions field.

    The injection occurs before each test method execution, after each test assertAll() is invoked to evaluate all test assertions.

    A nested test class can provide a SoftAssertions field when it extends this extension or can inherit the parent's Soft assertions field

    This extension throws an IllegalStateException if:

    • the test class lifecycle is TestInstance.Lifecycle.PER_CLASS (see explanation below).
    • multiple SoftAssertions fields are found
    • no SoftAssertions field is found

    Detecting multiple SoftAssertions fields is a best effort at the time of this writing, some cases are not detected.

    Limitations:

    1. Cannot be used with test context that have PER_CLASS life cycle as the same SoftAssertions would be reused between tests.
    2. May exhibit unpredictable behaviour in concurrent test execution

    If you hit such limitations, consider using SoftAssertionsExtension instead.

    Example:

     @ExtendWith(SoftlyExtension.class)
     public class SoftlyExtensionExample {
    
       // initialized by the SoftlyExtension extension
       private SoftAssertions soft;
    
       @Test
       public void chained_soft_assertions_example() {
         String name = "Michael Jordan - Bulls";
         soft.assertThat(name)
             .startsWith("Mi")
             .contains("Bulls");
         // no need to call softly.assertAll(), this is done by the extension
       }
    
       // nested classes test work too
       @Nested
       class NestedExample {
    
         @Test
         public void football_assertions_example() {
           String kylian = "Kylian Mbappé";
           soft.assertThat(kylian)
               .startsWith("Ky")
               .contains("bap");
           // no need to call softly.assertAll(), this is done by the extension
         }
       }
     } 
    Author:
    Arthur Mita
    • Field Detail

      • SOFTLY_EXTENSION_NAMESPACE

        private static final org.junit.jupiter.api.extension.ExtensionContext.Namespace SOFTLY_EXTENSION_NAMESPACE
    • Constructor Detail

      • SoftlyExtension

        public SoftlyExtension()
    • Method Detail

      • postProcessTestInstance

        public void postProcessTestInstance​(Object testInstance,
                                            org.junit.jupiter.api.extension.ExtensionContext extensionContext)
                                     throws Exception
        Specified by:
        postProcessTestInstance in interface org.junit.jupiter.api.extension.TestInstancePostProcessor
        Throws:
        Exception
      • afterTestExecution

        public void afterTestExecution​(org.junit.jupiter.api.extension.ExtensionContext extensionContext)
                                throws Exception
        Specified by:
        afterTestExecution in interface org.junit.jupiter.api.extension.AfterTestExecutionCallback
        Throws:
        Exception
      • getParent

        private static Optional<org.junit.jupiter.api.extension.ExtensionContext> getParent​(Optional<org.junit.jupiter.api.extension.ExtensionContext> currentContext)
      • isPerClassLifeCycle

        private static boolean isPerClassLifeCycle​(org.junit.jupiter.api.extension.ExtensionContext methodExtensionContext)
      • checkTooManySoftAssertionsFields

        private static void checkTooManySoftAssertionsFields​(Collection<Field> softAssertionsFields)
      • getStore

        private static org.junit.jupiter.api.extension.ExtensionContext.Store getStore​(org.junit.jupiter.api.extension.ExtensionContext extensionContext)