簡體   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