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"));
}