如何访问注解值(JUnit 4 ->JUnit 5)

w41d8nur  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(181)

我正在尝试将一个项目从JUnit 4移植到JUnit 5。该项目包含一个定制运行器,该运行器具有一个侦听器,该侦听器检测测试是否具有某个注解(@GradedTest)并访问注解的键-值对。例如,它可以访问与以下代码中的namepoints关联的值:

@Test
@GradedTest(name = "greet() test", points = "1")
public void defaultGreeting() {
    assertEquals(GREETING, unit.greet());
}

现有的JUnit 4代码有一个listener,它扩展了RunListener并覆盖了testStarted()

@Override
public void testStarted(Description description) throws Exception {
    super.testStarted(description);

    this.currentGradedTestResult = null;

    GradedTest gradedTestAnnotation = description.getAnnotation(GradedTest.class);
    if (gradedTestAnnotation != null) {
        this.currentGradedTestResult =  new GradedTestResult(
                gradedTestAnnotation.name(),
                gradedTestAnnotation.number(),
                gradedTestAnnotation.points(),
                gradedTestAnnotation.visibility()
        );
    }
}

注意,这里使用了Description.getAnnotation()
我正在尝试切换到JUnit平台启动器API。我可以使用LauncherDiscoveryRequestBuilder来选择要运行的测试,并且可以创建扩展SummaryGeneratingListener和覆盖executionStarted(TestIdentifier testIdentifier)的侦听器。但是,我看不到从TestIdentifier获取注解及其值的方法。
在JUnit 5中,Description.getAnnotation()的等价物是什么,或者获取测试注解值的新方法是什么?

pvcm50d1

pvcm50d11#

我确实找到了一种获取注解的方法,但我不知道它有多健壮。下面是我重写SummaryGeneratingListener.executionStarted(TestIdentifier identifier)的方法:

@Override
public void executionStarted(TestIdentifier identifier) {
    super.executionStarted(identifier);
    this.currentGradedTestResult = null;

    // Check if this is an atomic test, not a container.
    if (identifier.isTest()) {
        // Check if the test's source is provided.
        TestSource source = identifier.getSource().orElse(null);
        // If so, and if it's a MethodSource, get and use the annotation if present.
        if (source != null && source instanceof MethodSource) {
            GradedTest gradedTestAnnotation = ((MethodSource) source).getJavaMethod().getAnnotation(GradedTest.class);
            if (gradedTestAnnotation != null) {
                this.currentGradedTestResult = new GradedTestResult(
                        gradedTestAnnotation.name(),
                        gradedTestAnnotation.number(),
                        gradedTestAnnotation.points(),
                        gradedTestAnnotation.visibility()
                );

                this.currentGradedTestResult.setScore(gradedTestAnnotation.points());
            }
        }
    }

    this.testOutput = new ByteArrayOutputStream();
    System.setOut(new PrintStream(this.testOutput));
}

薄弱环节是TestIdentifier.getSource()。文档中说它获取“表示的测试或容器的源代码,* 如果可用 *。”它对我的测试有效,但我不知道在什么情况下源代码是(不)可用的。
我提供这个作为一个解决方案,但不标记为已回答,以防有更好的解决方案。如果有人感兴趣,有the commits

相关问题