Sie haben Recht, die Annotation Processing API (mit einer Schein-Bibliothek wie Easymock) zu verspotten ist schmerzhaft. Ich habe es versucht und es ist ziemlich schnell kaputt gegangen. Sie müssen viele Methodenaufruferwartungen einrichten. Die Tests werden unwartbar.
Ein state-based Testansatz arbeitete für mich einigermaßen gut. Ich musste die Teile der javax.lang.model.* API I needed for my tests implementieren. (Das waren nur < 350 Zeilen Code.)
Dies ist der Teil eines Tests, um die Objekte javax.lang.model zu initiieren. Nach dem Setup sollte das Modell den gleichen Status wie die Java-Compiler-Implementierung haben.
DeclaredType typeArgument = declaredType(classElement("returnTypeName"));
DeclaredType validReturnType = declaredType(interfaceElement(GENERATOR_TYPE_NAME), typeArgument);
TypeParameterElement typeParameter = typeParameterElement();
ExecutableElement methodExecutableElement = Model.methodExecutableElement(name, validReturnType, typeParameter);
Die statischen Factory-Methoden sind in der Klasse definiert Model
die javax.lang.model implementieren. * Klassen. Zum Beispiel declaredType
. (Alle nicht unterstützten Operationen Ausnahmen werfen.)
public static DeclaredType declaredType(final Element element, final TypeMirror... argumentTypes) {
return new DeclaredType(){
@Override public Element asElement() {
return element;
}
@Override public List<? extends TypeMirror> getTypeArguments() {
return Arrays.asList(argumentTypes);
}
@Override public String toString() {
return format("DeclareTypeModel[element=%s, argumentTypes=%s]",
element, Arrays.toString(argumentTypes));
}
@Override public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitDeclared(this, p);
}
@Override public boolean equals(Object obj) { throw new UnsupportedOperationException(); }
@Override public int hashCode() { throw new UnsupportedOperationException(); }
@Override public TypeKind getKind() { throw new UnsupportedOperationException(); }
@Override public TypeMirror getEnclosingType() { throw new UnsupportedOperationException(); }
};
}
Der Rest des Tests überprüft das Verhalten der Klasse unter Test.
Method actual = new Method(environment(), methodExecutableElement);
Method expected = new Method(..);
assertEquals(expected, actual);
Sie können sich die source code of the Quickcheck @Samples and @Iterables source code generator tests ansehen. (Der Code ist noch nicht optimal. Die Methodenklasse hat viele Parameter und die Parameterklasse wird nicht in einem eigenen Test getestet, sondern als Teil des Methodentests. Sie sollte dennoch den Ansatz verdeutlichen.)
Viel Glück!