繁体   English   中英

如何将此测试规则转换为 JUnit5?

[英]How do I convert this test rule to JUnit5?

我有一些使用 junit4 的自定义规则,我想将其转换为 junit5。 但是我找不到关于迁移 MethodRule 实现的好文档,除了我应该使用 junit5 扩展而不是规则。

public class MyRule implements MethodRule {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyRule.class);

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface MyAnnotation { }

    @Override
    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
        Statement result = statement;
        if (hasMyAnnotation(frameworkMethod)) {
                result = new Statement() {
                    @Override
                    public void evaluate() {
                        LOGGER.info("Skipping test");
                    }
                };
            }
        }
        return result;
    }

    private static boolean hasMyAnnotation(final Annotatable frameworkMethod) {
        return frameworkMethod.getAnnotation(MyAnnotation.class) != null;
    }

我的 class 正在使用 junit4 StatementFrameworkMethod等来确定我的方法是否有注释……然后跳过它。 我该如何转换?

解决方案 1,使用自定义注释禁用测试
JUnit 5 提供了一种可以控制是否应该运行测试的扩展。 这是通过实现ExecutionCondition接口来定义的。
扩展实现:

import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junit.platform.commons.util.AnnotationUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;

public class SkipConditionExtension implements ExecutionCondition {
    private static final Logger LOGGER = LoggerFactory.getLogger(SkipConditionExtension.class);

    @Override
    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
        AnnotatedElement element = context.getElement().orElse(null);

        if (hasMyAnnotation(element, MyAnnotation.class)) {
            LOGGER.info(() ->"Skipping test");
            return ConditionEvaluationResult.disabled(String.format("Skipped test: %s by @MyAnnotation", element));
        }

        return ConditionEvaluationResult.enabled("Test enabled");
    }

    private <T extends Annotation>  boolean hasMyAnnotation(final AnnotatedElement element, Class<T> annotation) {
        return element != null && AnnotationUtils.findAnnotation(element, annotation).isPresent();
    }
}

注册扩展:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(SkipConditionExtension.class)
public class TestObject {
    @Test
    public void test1() {

    }

    @Test
    @MyAnnotation
    public void test2() {

    }
}

Output:

INFO: Skipping test
Skipped test: public void com.test.TestObject.test2() by @MyAnnotation

解决方案 2,通过调用拦截器跳过测试
InvocationInterceptor iterface 为希望拦截调用以进行测试的扩展定义了 API。
当前实施的行为与您之前的Rule完全一样。
扩展实现:

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junit.platform.commons.util.AnnotationUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

public class SkipCondition implements InvocationInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(SkipConditionExtension.class);

    @Override
    public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
        AnnotatedElement element = extensionContext.getElement().orElse(null);
        if (hasMyAnnotation(element, MyAnnotation.class)) {
            LOGGER.info(() ->"Skipping test");
            invocation.skip();
        } else {
            invocation.proceed();
        }
    }

    private <T extends Annotation>  boolean hasMyAnnotation(final AnnotatedElement element, Class<T> annotation) {
        return element != null && AnnotationUtils.findAnnotation(element, annotation).isPresent();
    }
}

注册扩展:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(SkipCondition.class)
public class TestObject {
    @Test
    public void test1() {

    }

    @Test
    @MyAnnotation
    public void test2() {

    }
}

请注意,您可以根据文档执行自动扩展注册。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM