2014-12-18 5 views
3

스프링 webmvc 주석을 읽고 찾은 내용을 기반으로 코드를 생성하는 AnnotationProcessor가 있습니다.TypeMirror를 인스턴스화하는 방법

코드는 훌륭하게 작동하지만, javax.lang.model.type.TypeMirror을 인수로 사용하여 제네릭을 포함한 문자열 유형 표현을 돌려주는 방법을 테스트하는 방법을 알아야합니다 (예 : java.util.Map<java.lang.String, java.util.List<java.lang.String>>은 . 나는 TypeMirror 인수로 Map<String, List<String>>를 나타내는 통과 그래서

을 위해 단위 테스트에이 방법을 (나는이 대답에 내 코드를 기반으로 : Getting the qualified class name of generic type with Java 6 annotation processor). 나는에 모의하거나 좋아하거나 단위 테스트 중에 TypeMirror에를 만들 것을

실제 코드는입니다. 유사하게, 이것이 http://www.docjar.com/docs/api/com/sun/tools/javac/code/Symbol $ VarSymbol.html

그리고 TypeMirror에의 IMPL : 나는 VariableElement.asType()를 사용하지만, 디버거를 실행해야합니다는 VariableElement의 실제 구현이 핵심 자바 클래스의 API의 일부임을 발견하는 날 리드 의 JDK의 비공개 대면 부분에 장사

차라리 내부 자바 유형을 인스턴스화 갈 것 http://www.docjar.com/docs/api/com/sun/tools/javac/code/Type $ ClassType.html - 인스턴스화하는 "올바른"방법은 무엇 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); 
} 

답변

3

, 나는 "그래서 그냥 모의를 생성, 그것은 인터페이스입니다."라고 말하고 싶지만 이 경우에, 당신은 틀린 솔기를 시험하고 있다고 생각합니다.

이 경우 테스트중인 실제 단위는 익명으로 선언 된 SimpleTypeVisitor 구현입니다. 전체 typeToString 메서드를 실제로 테스트하려면 구현 한 6 가지 메서드가 모두 예상되는 동작과 일치하는지 확인해야합니다. 따라서 익명 구현을 구체적인 구현으로 승격시키고 해당 메소드를 테스트해야합니다. 그들 각각은 적어도 하나의 테스트를 가지고 있어야하며 그 테스트에서는 재귀 호출을 처리하기 위해 typeToString을 조롱 할 수 있습니다.