Как вы обнаружили, вам нужно добавить @Retention(RUNTIME)
к вашей составной аннотации, чтобы JUnit мог ее увидеть. Аннотации в Java имеют три разные политики хранения:
RetentionPolicy.SOURCE
Аннотации должны отбрасываться компилятором.
RetentionPolicy.CLASS
Аннотации должны быть записаны в файле классов компилятором, но их не нужно сохранять ВМ во время выполнения. Это поведение по умолчанию. [выделение добавлено]
RetentionPolicy.RUNTIME
Аннотации должны быть записаны в файле класса компилятором и сохранены виртуальной машиной во время выполнения, чтобы их можно было читать рефлексивно.
Как я Выделено выше, если вы явно не добавляете @Retention(...)
, тогда используется политика CLASS
. Это не будет работать с JUnit, потому что JUnit не сканирует файлы *.class
(т. Е. Байт-код) на наличие аннотаций, а сканирует классы загруженные , чтобы найти методы тестирования. Без политики хранения RUNTIME
ваша аннотация недоступна для отражения, поэтому JUnit никогда ее не видит и, следовательно, не выполняет тест.
@Target
аннотация:
Указывает контексты, в которых применяется тип аннотации. Контексты объявления и контексты типа, в которых может применяться тип аннотации, определены в JLS 9.6.4.1 и обозначены в исходном коде константами перечисления java.lang.annotation.ElementType
.
Если @Target
мета-аннотации нет в типе аннотации T
, тогда аннотацию типа T
можно записать в качестве модификатора для любого объявления, кроме объявления параметра типа.
Если @Target
присутствует метааннотация, компилятор будет применять ограничения на использование, указанные в константах ElementType
, в соответствии с JLS 9.7.4.
В моем ответе на другой ваш вопрос я использовал:
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
Поскольку это те же самые цели, которые используются @ParameterizedTest
, Я подумал, что было бы неплохо ограничить его METHOD
, так как разработчики @ParameterizedTest
, по-видимому, считают, что расширение параметризованных тестов должно напрямую расширять только методы (см. §5 Модель расширения ). В том числе ANNOTATION_TYPE
позволяет размещать составную аннотацию в другой аннотации, создавая еще одну составную аннотацию.
Вы также увидите, что я включил @Documented
:
Если аннотация @Documented
присутствует в объявлении типа аннотации A
, то любая аннотация @A
на элементе считается частью открытого элемента c контракта элемента. Более подробно, когда тип аннотации A
помечен Documented
, наличие и значение аннотаций типа A
являются частью публикации c Контракт элементов A
комментирует. И наоборот, если тип аннотации B
не аннотирован Documented
, наличие и значение аннотаций B
не являются частью договора c на публикацию элементы B
комментирует. Конкретно, если аннотированный тип аннотации Documented
, по умолчанию такой инструмент, как javado c, будет отображать аннотации этого типа в своем выводе, в то время как аннотации типов аннотации без Documented
не будут отображаться.
Обратите внимание, что эти аннотации - @Retention
, @Target
и @Documented
- не указывают c для JUnit. Эти аннотации имеют основополагающее значение для работы аннотаций в Java, и каждая из них находится в пакете java.lang.annotation
.