在JUnit 5中正确设置(系统)属性

bea*_*u13 4 java junit junit5

我们使用类似于系统规则的方法来处理JUnit 4测试中的(系统)属性.这样做的主要原因是在每次测试后清理环境,以便其他测试不会无意中依赖于可能的副作用.

自JUnit 5发布以来,我想知道是否有"JUnit 5方式"这样做?

bea*_*u13 13

JUnit Pioneer,一个“JUnit 5 扩展包”。它带有@ClearSystemProperty@SetSystemProperty。从文档

@ClearSystemProperty@SetSystemProperty注释可用于清除,分别为测试执行系统设置属性的值。这两个注释都适用于测试方法和类级别,既可重复又可组合。被注解的方法被执行后,注解中提到的属性将恢复到它们的原始值,或者如果它们之前没有的话将被清除。在测试期间更改的其他系统属性不会恢复。

例子:

@Test
@ClearSystemProperty(key = "some key")
@SetSystemProperty(key = "another key", value = "new value")
void test() {
    assertNull(System.getProperty("some key"));
    assertEquals("new value", System.getProperty("another key"));
}
Run Code Online (Sandbox Code Playgroud)


sch*_*ach 7

您可以使用扩展API.您可以创建一个注释,用于定义测试方法的扩展.

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();
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建扩展类:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用属性注释您的测试:

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

此解决方案仅支持每个测试的一个系统属性.如果要支持多个测试,可以使用嵌套注释,扩展也可以处理:

@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"));
}
Run Code Online (Sandbox Code Playgroud)

  • 它是JUnit5,因此它是Java8,因此它具有可重复的注释,并且实际上不需要向用户公开`@SystemProperties`注释 - 只需将`@SystemProperty`标记为可重复并调用`getAnnotationS`而不是`getAnnotation`. (3认同)