Wil Ferraciolli Wil Ferraciolli - 6 months ago 19
Java Question

How to reflection test entity annotations using JUnit

How can I test the integrity of annotations in Entity generated from Tables in a DB.
What I am trying to do is to test if the annotations are there and to check if they are filled out properly such as using Object data types instead of variables Eg.(Integers instead of int). check if Calendar type is used instead of Date type.

Currently I can create these tables and manually assign annotations such as:

@Entity
@Id,
@GeneratedValue(),
@Column(name="columnName"),
@Size(min = 1, max =20, message = "{ClassName.variableName.messageType"}),
@NotNull(message = "{ClassName.variableName.messageType"}),
@Temporal(TemporalType.DATE)...


The part where I am trying to solve is that i need to check the integrity of thesees annotations, such as if they are filled out properly or even there.
the code that i have to be tested is:

@Log
@Entity
@Table(name = "Notes")
@NamedQueries({
@NamedQuery(name = "Note.findAll", query = "SELECT n FROM Note n") })
public class Note implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(generator = "myGen")
@Column(name = "ID")
private String id;

@Column(name = "NOTE_OWNER")
@Size(min = 0, max = 20, message = "{Notes.owner.Invalid}")
private String owner;

@Column(name = "NOTE_CAPTION")
@Size(min = 0, max = 255, message = "{Notes.caption.Invalid}")
private String caption;

Answer

Ok, assuming that what you want to do is actually useful, you can of course list all the Annotations, perhaps with a parameterized test (as you want to do the same stuff for all your classes).

Class<?> clz = Note.class();
Annotation[] annotations = clz.getAnnotations(); // lists all
Table table = clz.getAnnotation(Table.class); // get the Table annotation

Of course you can do the same thing for Fields...

Field[] fields = clz.getDeclaredFields();
for(Field field : fields) {
  Annotation[] annotations = field.getAnnotations(); // lists all
  Column column = clz.getAnnotation(Column.class); // get the Column annotation
}

...and methods (same code). I personally would tend to implement specific rules for each annotation instead of trying to parse all annotations dynamically (ok, personally I wouldn't write a class without having a test for it, so I wouldn't have that problem, but that's another matter ;-).

For the test itself...

@RunWith(Parameterized.class)
public class EntityTest {

    @Parameters(name = "entity #{index} \"{0}\" must be properly annotated")
    public static Collection<Object[]> data() {
    return Arrays.asList(new Object[][] {
        { Note.class },
        { Something.class }
    });
    }

    private final Class<?> entityClass;

    public EntityTest(final Class<?> entityClass) {
    this.entityClass = entityClass;
    }

    @Test
    public void someTest() {
       // test your entityClasss
    }

}
Comments