JUnit5-Jupiter:组合(="meta")注释无法解析为注释定义 [英] JUnit5-Jupiter: Composed (="meta") annotation does not resolve to annotation definition
问题描述
我定义了自己的JUnit批注:
I defined my own JUnit annotation:
@ParameterizedTest
@MethodSource("myorg.qa.ccrtesting.DataProviders#standardDataProvider")
@Tags({@Tag("ccr"), @Tag("standard")})
public @interface CcrStandardTest {
}
然后,我可以在测试中使用该批注:
Then, I was able to use that annotation in my tests:
@CcrStandardTest
public void E0010_contact_standard (String testData) {
...
- 我的跑步配置:
JVM选项:-ea
类:myorg.qa.ccrtesting.ccrstandardtests.CcrStanConTest
-这是IDE提出的(已验证为指向正确的类,其中包含我的原型测试方法) - My run configuration:
JVM options:-ea
Class:myorg.qa.ccrtesting.ccrstandardtests.CcrStanConTest
- This was suggested by the IDE (and is verified to point to the correct class, which holds my prototype test method) -
我尝试从测试方法签名中删除
String testData
,但是JUnit没有执行任何测试:No tests found
I tried removing
String testData
from the test method signature but then JUnit is not executing any tests:No tests found
- 在
@CcrStandardTest
下定义的注释似乎都没有应用 - IDE建议
suspicious combination @Test and parameterized source
(我已经知道@ParameterizedTest
暗示@Test
,只是不确定为什么IDE能够找到自定义注释,而JUnit却找不到?) - It seems like none of the annotations I defined under
@CcrStandardTest
are applied - IDE suggests
suspicious combination @Test and parameterized source
(I already know@ParameterizedTest
implies@Test
, just not sure why IDE is able to find the custom annotation but JUnit isn't?) RetentionPolicy.CLASS
注释由编译器记录在类文件中,但VM不必在运行时保留. 这是默认行为. [添加了重点]
RetentionPolicy.RUNTIME
注释由编译器记录在类文件中,并在运行时由VM保留,以便可以通过反射方式读取.
Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.
但是,结果为:jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [java.lang.String arg0] in method [public void...
当我在原型测试方法上方添加@Test
时,它会执行,但是:
When I add @Test
above my prototype test method, it executes but:
推荐答案
As you've discovered, you need to add @Retention(RUNTIME)
to your composed annotation in order for JUnit to see it. Annotations in Java have three different retention policies:
注释将被编译器丢弃.
Annotations are to be discarded by the compiler.
如上所述,如果您未明确添加@Retention(...)
,则会使用CLASS
策略.这不适用于JUnit,因为JUnit不会扫描*.class
文件(即字节码)中的注释,而是以反射方式扫描 loaded 类以找到测试方法.没有RUNTIME
保留策略,您的注释将无法反射访问,因此JUnit永远不会看到它,因此不会执行测试.
As I emphasized above, if you don't explicitly add @Retention(...)
then the CLASS
policy is used. This won't work with JUnit because JUnit doesn't scan the *.class
files (i.e. byte-code) for the annotations, it scans the loaded classes reflectively to find test methods. Without a RUNTIME
retention policy your annotation is not reflectively accessible, thus JUnit never sees it and consequently doesn't execute the test.
指示注释类型适用的上下文.在JLS 9.6.4.1中指定了可以在其中应用注释类型的声明上下文和类型上下文,并在源代码中用如果注释类型 If an 如果存在 If an 在回答您的其他问题时,我使用了: 因为这与§5扩展模型).并且包含 Because that's the same targets used by You'll also see I included 如果注释类型 If the annotation 请注意,这些注释( Notice that theses annotations— 这篇关于JUnit5-Jupiter:组合(="meta")注释无法解析为注释定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!T
上不存在@Target
元注释,则可以将类型为T
的注释写为除类型参数声明之外的任何声明的修饰符.@Target
meta-annotation is not present on an annotation type T
, then an annotation of type T
may be written as a modifier for any declaration except a type parameter declaration.@Target
元注释,则编译器将根据JLS 9.7.4强制执行ElementType
枚举常量指示的使用限制. @Target
meta-annotation is present, the compiler will enforce the usage restrictions indicated by ElementType
enum constants, in line with JLS 9.7.4. @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
ANNOTATION_TYPE
允许您将组合的注释放置在另一个注释上,从而创建另一个组合的注释.@ParameterizedTest
. I figured it was a good idea to restrict it to METHOD
since the designers of @ParameterizedTest
apparently feel that only methods should be directly extended by the parameterized-tests extension (see §5 Extension Model). And including ANNOTATION_TYPE
allows you to place your composed annotation on another annotation, creating yet another composed annotation.@Documented
:
A
的声明中存在注释@Documented
,则元素上的任何@A
注释均被视为该元素的公共合同的一部分.更详细地讲,当注释类型 A
用Documented
注释时,类型 A
的注释的存在和值是公共合同的一部分. A
元素的注释.相反,如果注释类型 B
没有用Documented
注释,则 B
注释的存在和值不属于元素公共合同的一部分. B
进行注释.具体来说,如果注释类型用Documented
注释,则默认情况下,像javadoc这样的工具将在其输出中显示该类型的注释,而不会显示不包含Documented
的注释类型的注释.
@Documented
is present on the declaration of an annotation type A
, then any @A
annotation on an element is considered part of the element's public contract. In more detail, when an annotation type A
is annotated with Documented
, the presence and value of annotations of type A
are a part of the public contract of the elements A
annotates. Conversely, if an annotation type B
is not annotated with Documented
, the presence and value of B
annotations are not part of the public contract of the elements B
annotates. Concretely, if an annotation type is annotated with Documented
, by default a tool like javadoc will display annotations of that type in its output while annotations of annotation types without Documented
will not be displayed.@Retention
,@Target
和@Documented
)并非特定于JUnit.这些注释是Java中注释如何工作的基础,并且每个注释都驻留在java.lang.annotation
程序包中.@Retention
, @Target
, and @Documented
—are not specific to JUnit. These annotations are fundamental to how annotations in Java work and each one resides in the java.lang.annotation
package.