如何使用jOOR对注解处理器进行单元测试?

注解处理器可以作为一种变通办法,将某些语言功能纳入Java语言。
jOOQ还具有注解处理器,可帮助验证以下方面的SQL语法:
普通的SQL使用(SQL注入风险)
SQL方言支持(防止在MySQL上使用仅Oracle功能)

单元测试注解处理器

单元测试注解处理器比使用它们要棘手得多。您的处理器挂接到Java编译器并操纵已编译的AST(或执行其他操作)。如果要测试自己的处理器,则需要运行Java编译器的测试,但这在常规项目设置中很难做到,特别是如果给定测试的预期行为是编译错误。
假设我们有以下两个注解:
@interface A {}
@interface B {}
现在,我们想建立一个@A必须始终伴随的规则@B。例如:
// This must not compile
@A
class Bad {}

// This is fine
@A @B
class Good {}
我们将使用注解处理器来执行该操作:
class AProcessor implements Processor {
boolean processed;
private ProcessingEnvironment processingEnv;

@Override
public Set<String> getSupportedOptions() {
    return Collections.emptySet();
}

@Override
public Set<String> getSupportedAnnotationTypes() {
    return Collections.singleton("*");
}

@Override
public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.RELEASE_8;
}

@Override
public void init(ProcessingEnvironment processingEnv) {
    this.processingEnv = processingEnv;
}

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    for (TypeElement e1 : annotations)
        if (e1.getQualifiedName().contentEquals(A.class.getName()))
            for (Element e2 : roundEnv.getElementsAnnotatedWith(e1))
                if (e2.getAnnotation(B.class) == null)
                    processingEnv.getMessager().printMessage(ERROR, "Annotation A must be accompanied by annotation B");

    this.processed = true;
    return false;
}

@Override
public Iterable<? extends Completion> getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) {
    return Collections.emptyList();
}

}
现在,这有效。我们可以通过将注解处理器添加到某些Maven编译器配置中并通过使用A和B注解几个类来轻松地手动进行验证。但是随后,有人更改了代码,我们没有注意到回归。我们该如何对它进行单元测试,而不是手动处理?
jOOR 0.9.10支持注解处理器
jOOR是我们在jOOQ内部使用的小开源反射库
jOOR有一个方便的API,可以javax.tools.JavaCompiler通过调用API Reflect.compile()。最新版本0.9.10现在带有一个可选CompileOptions参数,可以在其中注册注解处理器。
这意味着,我们现在可以编写一个非常简单的单元测试,如下所示
@Test
public void testCompileWithAnnotationProcessors() {
AProcessor p = new AProcessor();

try {
    Reflect.compile(
        "org.joor.test.FailAnnotationProcessing",
        ```
         package org.joor.test; 
         @A 
         public class FailAnnotationProcessing {
         }
        ```,
        new CompileOptions().processors(p)
    ).create().get();
    Assert.fail();
}
catch (ReflectException expected) {
    assertTrue(p.processed);
}

Reflect.compile(
    "org.joor.test.SucceedAnnotationProcessing",
    ```
     package org.joor.test; 
     @A @B 
     public class SucceedAnnotationProcessing {
     }
    ```,
    new CompileOptions().processors(p)
).create().get();
assertTrue(p.processed);

}
太简单!永远不会在注解处理器中再进行回归!
最后,开发这么多年我也总结了一套学习Java的资料与面试题,如果你在技术上面想提升自己的话,可以关注我,可以加一下我的Java学习交流群:970917008,有时间记得帮我点下转发让跟多的人看到哦。在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值