有条件地跳过 Junit 5 测试

Nov*_*ser 6 junit

在我的 Junit Jupiter API 5.5 测试中,我正在调用我的方法,该方法在内部对远程服务进行 HTTP 调用。现在,远程服务可能会关闭或行为不正确。我想跳过测试,以防远程服务未按预期运行。

@Test
void testMe() {
  // do something
  Result res1 = myObject.retrieveResults(params)
  // assert something

  Result res2 = myObject.retrieveResults(param2)
  //asert on results
}

Result retrieveResults(Parameters param) {
 // do something
  // call to remote service
  // if they do not give result throw CustomException()
  // return Result
}
Run Code Online (Sandbox Code Playgroud)

所以基本上在我的测试中我想检查是否myObject.retrieveResult抛出 CustomException 然后跳过该测试,否则正常评估。

Man*_*ami 14

在 JUnit 5 中,我们有两种不同的方法来完成此任务。

出于演示目的,我创建了一个基本类,它将请求发送到作为参数传递给其方法的 url ,并根据请求结果call(String url)返回true或。false该方法的主体在这里无关紧要。

使用Assumptions.assumeTrue()/assumeFalse()方法

Assumptions类为我们提供了两个重载方法 -assumeTrueassumeFalse。这个想法是,如果假设错误,测试将被跳过。

所以,测试会是这样的。

@Test
void call1() {
    Assumptions.assumeTrue(new EndpointChecker(), "Endpoint is not available");
    Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
Run Code Online (Sandbox Code Playgroud)

这是类的代码EndpointChecker

static class EndpointChecker implements BooleanSupplier {
    @Override
    public boolean getAsBoolean() {
        // check the endpoint here and return either true or false
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

运行测试时,将首先检查端点的可用性,如果可用,则将运行测试。

使用 JUnit 5 扩展机制。

那么,让我们从创建注释开始。这非常简单。

@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(EndpointAvailabilityCondition.class)
public @interface SkipWhenEndpointUnavailable {

    String uri();

}
Run Code Online (Sandbox Code Playgroud)

还有EndpointAvailabilityCondition班级。虽然看起来很大,但整体逻辑很简单。

import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;

public class EndpointAvailabilityCondition implements ExecutionCondition {

    @Override
    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
        final var optional = findAnnotation(context.getElement(), SkipWhenEndpointUnavailable.class);
        if (optional.isPresent()) {
            final SkipWhenEndpointUnavailable annotation = optional.get();
            final String uri = annotation.uri();
            // check connection here start
            boolean result = false; // dummy value
            // check connection here end
            if (result) {
                return ConditionEvaluationResult.enabled("Connection is up");
            } else {
                return ConditionEvaluationResult.disabled("Connection is down");
            }
        }
        return ConditionEvaluationResult.enabled("No assumptions, moving on...");
    }

}
Run Code Online (Sandbox Code Playgroud)

因此,我们可以在测试中执行以下操作。

@Test
@SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
    Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
Run Code Online (Sandbox Code Playgroud)

我们可以继续添加@Test注释@SkipWhenEndpointUnavailable并将其从测试代码中删除。就像这样:

@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(EndpointAvailabilityCondition.class)
@Test
public @interface SkipWhenEndpointUnavailable {

    String uri();

}
class HttpCallerTest {
    @SkipWhenEndpointUnavailable(uri = "https://www.google.com")
    void call2() {
        Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助。