Java中的参数化@Interface注解

BEW*_*ARB 2 java junit5

我有一个像这样的 @interface 注释类型 -

public @interface someAnnotation {
    String someVar() default "var_value";
}
Run Code Online (Sandbox Code Playgroud)

我想对someVar与此类似的 Junit5 测试进行参数化

@ParametrizedTest
@ValueSource(strings = {"val1","val2"})
@someAnnotation(someVar = ??)
void theTestMethod(String s){
    //test something
}
Run Code Online (Sandbox Code Playgroud)

我希望将 s 的值(由 valueSource 提供)加载到 someVar 中。显然这样的事情是行不通的 -

@someAnnotation(someVar = s)
Run Code Online (Sandbox Code Playgroud)

我还尝试通过实现来使用测试扩展BeforeEachCallback来访问ExtensionContext可以访问的 someVar,但我没有找到从 获取 ValueSource 值或方法参数值的方法ExtensionContext。有什么办法可以实现这一点吗?

Mat*_*nry 5

简而言之,Java 语言规范中有关注释的部分null指出,元素值不能是且只能是:

  • 常量表达式
  • 类文字
  • 枚举常量
  • 元素为上述之一的数组

因此,您所要求的内容是该语言不允许的。

据我所知,在测试中实现注释值的这种可变性的唯一方法是让测试生成源代码并动态编译它(或者等效地,直接生成字节码)。

从风格上来说,我认为除非你@ValueSource有超过 50 个元素,否则对于读者来说,写出每个案例会更简单、更清晰,如下所示:

@Test
@someAnnotation(someVar = "val1")
void theTestMethodVal1(){
    theTestMethodHelper("val1");
}

@Test
@someAnnotation(someVar = "val2")
void theTestMethodVal2(){
    theTestMethodHelper("val2");
}

void theTestMethodHelper(String s){
    //test something
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,我不清楚这样的测试的目标是什么。

"val1"从上述方法主体中的硬编码可以清楚地看出,"val2"简单地将所需的值内联到方法主体中,而不是跳过阅读所需的反射环,会更清晰、更简洁。从方法上的注释动态地获得相同的值。