Properly set (system) properties in JUnit 5

后端 未结 3 878

We are using an approach similar to System Rules to handle (system) properties in our JUnit 4 tests. The main reason for this is to clean up the environment after each test,

3条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-12 00:49

    You can use the extension API. You could create an annotation which defines your extension to a test method.

    import org.junit.jupiter.api.extension.ExtendWith;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @ExtendWith(SystemPropertyExtension.class)
    public @interface SystemProperty {
    
        String key();
    
        String value();
    }
    

    Then, you can create the extension class:

    import org.junit.jupiter.api.extension.AfterEachCallback;
    import org.junit.jupiter.api.extension.BeforeEachCallback;
    import org.junit.jupiter.api.extension.ExtensionContext;
    
    public class SystemPropertyExtension implements AfterEachCallback, BeforeEachCallback {
    
        @Override
        public void afterEach(ExtensionContext extensionContext) throws Exception {
            SystemProperty annotation = extensionContext.getTestMethod().get().getAnnotation(SystemProperty.class);
            System.clearProperty(annotation.key());
        }
    
        @Override
        public void beforeEach(ExtensionContext extensionContext) throws Exception {
            SystemProperty annotation = extensionContext.getTestMethod().get().getAnnotation(SystemProperty.class);
            System.setProperty(annotation.key(), annotation.value());
        }
    }
    

    Finally, you can annotate your test with properties:

    @Test
    @SystemProperty(key = "key", value = "value")
    void testPropertey() {
        System.out.println(System.getProperty("key"));
    }
    

    This solution supports only one system property for each test. If you want to support multiple test, you could use a nested annotation and the extension could handle this as well:

    @Test
    @SystemProperties({
        @SystemProperty(key = "key1", value = "value"),
        @SystemProperty(key = "key2", value = "value")
    })
    void testPropertey() {
        System.out.println(System.getProperty("key1"));
        System.out.println(System.getProperty("key2"));
    }
    

提交回复
热议问题