如何为 Java 注释处理器编写自动化单元测试? [英] How to write automated unit tests for java annotation processor?

查看:24
本文介绍了如何为 Java 注释处理器编写自动化单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验 Java 注释处理器.我能够使用JavaCompiler"编写集成测试(实际上我现在正在使用hickory").我可以运行编译过程并分析输出.问题:即使我的注释处理器中没有任何代码,单个测试也会运行大约半秒.这对于以 TDD 风格使用它的时间太长了.

I'm experimenting with java annotation processors. I'm able to write integration tests using the "JavaCompiler" (in fact I'm using "hickory" at the moment). I can run the compile process and analyse the output. The Problem: a single test runs for about half a second even without any code in my annotation processor. This is way too long to using it in TDD style.

模拟依赖项对我来说似乎很难(我必须模拟整个javax.lang.model.element"包).有人成功为注释处理器 (Java 6) 编写单元测试吗?如果不是……你的方法是什么?

Mocking away the dependencies seems very hard for me (I would have to mock out the entire "javax.lang.model.element" package). Have someone succeed to write unit tests for an annotation processor (Java 6)? If not ... what would be your approach?

推荐答案

你说得对,嘲笑注释处理 API(使用像 easymock 这样的模拟库)是痛苦的.我尝试了这种方法,它很快就崩溃了.您必须设置许多方法调用期望.测试变得不可维护.

You're right mocking the annotation processing API (with a mock library like easymock) is painful. I tried this approach and it broke down pretty rapidly. You have to setup to many method call expectations. The tests become unmaintainable.

基于状态的测试方法对我来说效果很好.我必须实现 javax.lang.model.* 我的测试需要的 API.(那只有 <350 行代码.)

A state-based test approach worked for me reasonably well. I had to implement the parts of the javax.lang.model.* API I needed for my tests. (That were only < 350 lines of code.)

这是启动 javax.lang.model 对象的测试的一部分.设置完成后,模型应该处于与 Java 编译器实现相同的状态.

This is the part of a test to initiate the javax.lang.model objects. After the setup the model should be in the same state as the Java compiler implementation.

DeclaredType typeArgument = declaredType(classElement("returnTypeName"));
DeclaredType validReturnType = declaredType(interfaceElement(GENERATOR_TYPE_NAME), typeArgument);
TypeParameterElement typeParameter = typeParameterElement();
ExecutableElement methodExecutableElement = Model.methodExecutableElement(name, validReturnType, typeParameter);

静态工厂方法在实现 javax.lang.model.* 类的 Model 类中定义.例如declaredType.(所有不受支持的操作都会抛出异常.)

The static factory methods are defined in the class Model implementing the javax.lang.model.* classes. For example declaredType. (All unsupported operations will throw exceptions.)

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(); }
    };
}

测试的其余部分验证被测类的行为.

The rest of the test verifies the behavior of the class under test.

Method actual = new Method(environment(), methodExecutableElement);
Method expected = new Method(..);
assertEquals(expected, actual);

你可以看看Quickcheck @Samples 和@Iterables 源代码生成器测试的源代码.(代码还不是最优的.Method 类有很多参数,Parameter 类没有在它自己的测试中进行测试,而是作为 Method 测试的一部分.不过它应该说明该方法.)

You can have a look at the source code of the Quickcheck @Samples and @Iterables source code generator tests. (The code is not optimal, yet. The Method class has to many parameters and the Parameter class is not tested in its own test but as part of the Method test. It should illustrate the approach nevertheless.)

维尔格鲁克!

这篇关于如何为 Java 注释处理器编写自动化单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆