Вы правы, издеваться над API обработки аннотаций (с фиктивной библиотекой, такой как easymock) очень болезненно. Я попробовал этот подход, и он сломался довольно быстро. Вы должны настроить многие ожидания вызова метода. Испытания становятся неосуществимыми.
A подход к тестированию на основе состояния работал для меня достаточно хорошо. Мне пришлось реализовать части API javax.lang.model. *, Которые были необходимы для моих тестов . (Это было всего <350 строк кода.) </p>
Это часть теста для инициации объектов javax.lang.model. После настройки модель должна быть в том же состоянии, что и реализация компилятора Java.
DeclaredType typeArgument = declaredType(classElement("returnTypeName"));
DeclaredType validReturnType = declaredType(interfaceElement(GENERATOR_TYPE_NAME), typeArgument);
TypeParameterElement typeParameter = typeParameterElement();
ExecutableElement methodExecutableElement = Model.methodExecutableElement(name, validReturnType, typeParameter);
Статические методы фабрики определены в классе Model
, реализующем классы javax.lang.model. *. Например declaredType
. (Все неподдерживаемые операции будут вызывать исключения.)
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(); }
};
}
Остальная часть теста проверяет поведение тестируемого класса.
Method actual = new Method(environment(), methodExecutableElement);
Method expected = new Method(..);
assertEquals(expected, actual);
Вы можете посмотреть исходный код тестов генератора исходного кода Quickcheck @Samples и @Iterables . (Код пока не оптимален. Класс Method имеет много параметров, а класс Parameter тестируется не в своем собственном тесте, а как часть теста метода. Тем не менее, он должен иллюстрировать подход.)
Viel Glück!