Chris
Chris

Reputation: 586

Custom Annotation not found while unit testing

say i've an Annotation like that:

@Retention(RetentionPolicy.RUNTIME)
public @interface AutoConvert {
    boolean enabled() default true;
}

and class annotated with it:

@AutoConvert
public class ExampleCommandToExample extends BaseConverter{}

On the superclass i'am doing the following:

public void convert(){
  Annotation annotation = (AutoConvert) this.getClass().getAnnotation(AutoConvert.class);
}

Everything works fine on runtime! Annotation is getting found and properly set!

But! While unit testing the convert method with JUnit: this.getClass().getAnnotation(AutoConvert.class) always returns null.

The test looks like this:

@Test
public void convertTest(){
    //when
    exampleCommandToExample.convert();
}

Are custom annotations not being found by reflection while running unit tests? Does anyone has an answer for me? I would really really appreciate it.

Thank you in advance.

EDIT: Alright it seems to be grounded in the kind of intatiation... I do the following:

exampleCommandToExample = new ExampleCommandToExample() {
    @Override
    public Type overideSomeMethod() {
        return type;
    }
};

May it be possible that an instance looses all it's annotations if I override some methods on instantiation?

Upvotes: 2

Views: 2859

Answers (1)

Antot
Antot

Reputation: 3964

Since exampleCommandToExample ref represents an instance of an anonymous class, the call this.getClass().getAnnotation(AutoConvert.class) collects the annotations at its level and all inherited ones.

However, @AutoConvert in this example of anonymous implementation is not inherited, that is why getAnnotation returns null, which corresponds exactly to the behavior declared in Java API:

Returns this element's annotation for the specified type if such an annotation is present, else null.

To solve the issue, simply add

import java.lang.annotation.Inherited;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface AutoConvert { /* no changes */ }

@Inherited will make the annotation visible for the anonymous implementation.

Upvotes: 4

Related Questions