当前位置: 首页 > 知识库问答 >
问题:

如何实例化TypeMirror

咸昊昊
2023-03-14

我有一个NotificationProcessor,它可以读取Springwebmvc注释并根据它发现的内容生成代码。

代码运行得很好,但是我需要弄清楚如何对一个方法进行单元测试,该方法将< code > javax . lang . model . type . type mirror 作为参数,并返回它的字符串类型表示,包括泛型(例如< code>java.util.Map

因此,为了对此方法进行单元测试(我的代码基于此答案:使用 Java 6 注释处理器获取泛型类型的限定类名),我想在单元测试期间模拟或创建 TypeMirror。

在我的实际代码中,我得到了使用variablelement所需的类型镜像。asType(),但运行调试器会让我发现VariableElement的实际实现是一个核心Java类,而不是api的一部分:http://www.docjar.com/docs/api/com/sun/tools/javac/code/Symbol$VarSymbol.html

TypeMirror impl是这样的,同样埋在jdk的一个非面向公众的部分:http://www.docjar.com/docs/api/com/sun/tools/javac/code/Type$ClassType.html

我宁愿不去实例化内部java类型——实例化TypeMirror(或VariableElement)的“正确”方法是什么?有人嘲笑过一个他们可以给我举个例子的地方吗?

这是我想要的单元测试方法:

private void typeToString(final TypeMirror type, final StringBuilder result,
                          final char innerClassSeparator) {
    type.accept(new SimpleTypeVisitor7<Void, Void>() {
        @Override
        public Void visitDeclared(DeclaredType declaredType, Void v) {
            TypeElement typeElement = (TypeElement) declaredType.asElement();
            String rawType = rawTypeToString(typeElement, innerClassSeparator);
            result.append(Util.getUnqualifiedClassName(rawType));
            //java.lang.* is auto-included by the compiler for all classes
            if (!rawType.startsWith("java.lang")) {
                importTypes.add(rawType);
            }
            List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
            if (!typeArguments.isEmpty()) {
                result.append("<");
                for (int i = 0; i < typeArguments.size(); i++) {
                    if (i != 0) {
                        result.append(", ");
                    }
                    typeToString(typeArguments.get(i), result, innerClassSeparator);
                }
                result.append(">");
            }
            return null;
        }

        @Override
        public Void visitPrimitive(PrimitiveType primitiveType, Void v) {
            result.append(box((PrimitiveType) type).getName());
            return null;
        }

        @Override
        public Void visitArray(ArrayType arrayType, Void v) {
            TypeMirror type = arrayType.getComponentType();
            if (type instanceof PrimitiveType) {
                result.append(type.toString()); // Don't box, since this is an array.
            } else {
                typeToString(arrayType.getComponentType(), result, innerClassSeparator);
            }
            result.append("[]");
            return null;
        }

        @Override
        public Void visitTypeVariable(TypeVariable typeVariable, Void v) {
            result.append(typeVariable.asElement().getSimpleName());
            return null;
        }

        @Override
        public Void visitError(ErrorType errorType, Void v) {
            // Error type found, a type may not yet have been generated, but we need the type
            // so we can generate the correct code in anticipation of the type being available
            // to the compiler.

            // Paramterized types which don't exist are returned as an error type whose name is "<any>"
            if ("<any>".equals(errorType.toString())) {
                throw new CodeGenerationIncompleteException(
                        "Type reported as <any> is likely a not-yet generated parameterized type.");
            }
            result.append(errorType.toString());
            return null;
        }

        @Override
        protected Void defaultAction(TypeMirror typeMirror, Void v) {
            result.append("void");
            return null;
        }
    }, null);
}

共有1个答案

卫学真
2023-03-14

对于一般情况,我会说“这是一个接口,所以只需创建一个模拟。”在这种情况下,我认为你测试了错误的接缝。

在本例中,真正的测试单元是匿名声明的SimpleTypeVisitor实现。考虑到要真正测试整个类型字符串方法,您必须验证您实现的所有六个方法都与其预期行为一致。因此,您应该将匿名实现提升为具体实现,并测试这些方法。它们中的每一个都应该至少有一个测试,在这些测试中,您可以模拟类型字符串,以处理递归调用。

 类似资料:
  • 我正在为Eclipse Juno编写一个插件,我想使用类AbstractSourceLookupDirector。当我查看API时,它说它有一个构造函数,但是当我在代码中使用以下语句时,它说“不能实例化类型AbstractSourceLookupDirector” AbstractSourceLookupDirector srclookupDir=新的AbstractSourceLookupDir

  • 问题内容: 我如何使这种事情起作用?我可以检查,但不能。有办法可以做到吗? 问题答案: 这是不可能的,因为在泛型编译时会擦除数据类型。做到这一点的唯一可能方法是编写某种包装,该包装保存列表包含的类型:

  • 问题内容: 我看到了无数的示例和教程,这些示例和教程展示了如何通过仅设置文件的权限位来创建文件,并且所有这些文件都“作弊”。我想知道/找出如何在创建/更新文件期间正确实例化os.FileMode以提供给编写者。 下面是一个简单的示例: 在上面的基本功能中,权限位0664被设置,尽管这有时可能有意义,但我还是希望有一种正确设置文件模式的正确方法。从上面可以看到,一个常见的示例是UID / GID是已

  • 问题内容: 我想要的只是使用一些并发Set(看起来根本不存在)。Java用于实现该行为。我想在Scala中做类似的事情,所以我创建了Scala HashMap(或Java ConcurrentHashMap)实例,并尝试添加一些元组: 当然,由于Unit是抽象的也是最终的,因此这使编译过程崩溃了。 如何使这项工作?我应该使用/ 代替吗?我必须确保没有人插入任何值。 感谢帮助 问题答案: 您可以只使

  • 我有一个类,它有一个可嵌入的类: 我需要实例化“UserPK”,但它不起作用。救命啊! 我试图实例化它作为一个内部类,作为一个单一的类...它编译,但它不创建对象。

  • 问题内容: 最近,我一直在使用XML解析器。这对我来说仅仅是个开始,我设法了解了如何在Java即使用DOM解析器类,以及如何解析XML文档。 我想问自己的是如何允许抽象类(例如和)实例化新实例?然后在另一个示例中,我看到: 据我所知,您不能为抽象类和接口类实例化(换句话说,创建一个对象)。我对么? 难道和方法创建上面的抽象类的实例? 我是否缺少使用抽象类及其新对象的内容? 问题答案: 该方法是一个