我正在嘗試使用java註釋處理器。我能夠使用「JavaCompiler」編寫集成測試(實際上我現在使用「hickory」)。我可以運行編譯過程並分析輸出。問題:即使在我的註釋處理器中沒有任何代碼,單個測試仍可運行大約半秒鐘。在TDD風格中使用它太長了。 (我將不得不嘲笑整個「javax.lang.model.element」包)。讓某人成功爲註釋處理器(Java 6)編寫單元測試?如果不是......你會怎麼做?如何爲java註釋處理器編寫自動化單元測試?
回答
你是對的嘲笑註解處理API(帶有像easymock這樣的模擬庫)是痛苦的。我嘗試了這種方法,並且很快就崩潰了。您必須設置許多方法調用期望。測試變得不可維護。
A 基於狀態的測試方法合理地爲我工作。我必須執行javax.lang.model.* API I needed for my tests的部分。 (這只是< 350行代碼)。
這是啓動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);
的靜態工廠方法在實施javax.lang.model類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);
你可以看看source code of the Quickcheck @Samples and @Iterables source code generator tests。 (代碼還不是最優的,Method類有許多參數,Parameter類沒有在自己的測試中測試過,但作爲Method測試的一部分,它應該說明這個方法。)
VielGlück!
一個選項是將所有測試捆綁在一個類中。對於給定的一組測試,編譯等等的時間只有半秒,而測試的實際測試時間是可以接受的,我假設。
爲了簡單起見,我已經使用了http://hg.netbeans.org/core-main/raw-file/default/openide.util.lookup/test/unit/src/org/openide/util/test/AnnotationProcessorTestUtils.java,儘管這是基於java.io.File
,因此您的抱怨會帶來性能開銷。
托馬斯關於嘲笑整個JSR 269環境的建議將導致純粹的單元測試。您可能更想寫更多的集成測試,它會檢查處理器在javac中的實際運行情況,從而更確保它是正確的,但僅僅希望避免磁盤文件。這樣做需要你編寫一個模擬JavaFileManager
,這不幸並不像看起來那麼簡單,我沒有任何方便的例子,但你不應該嘲笑其他的東西,如Element
接口。
這是一個古老的問題,但似乎註解處理器測試的狀態沒有得到任何改善,所以我們今天發佈了Compile Testing。最好的文檔在package-info.java,但總體思路是有一個流暢的API用於在使用註釋處理器運行時測試編譯輸出。例如,該處理器生成一個匹配GeneratedHelloWorld.java
(金色文件中的類路徑上)的文件
ASSERT.about(javaSource())
.that(JavaFileObjects.forResource("HelloWorld.java"))
.processedWith(new MyAnnotationProcessor())
.compilesWithoutError()
.and().generatesSources(JavaFileObjects.forResource("GeneratedHelloWorld.java"));
測試。您也可以測試處理器產生錯誤輸出:
JavaFileObject fileObject = JavaFileObjects.forResource("HelloWorld.java");
ASSERT.about(javaSource())
.that(fileObject)
.processedWith(new NoHelloWorld())
.failsToCompile()
.withErrorContaining("No types named HelloWorld!").in(fileObject).onLine(23).atColumn(5);
這顯然比嘲諷,不像典型的集成測試簡單了很多,所有的輸出都存儲在內存中。
我處於類似的情況,所以我創建了Avatar庫。它不會給你一個沒有編譯的純單元測試的性能,但如果使用得當,你不應該看到太多的性能問題。
頭像可讓您編寫源文件,對其進行註釋並將其轉換爲單元測試中的元素。這使您可以單元測試消耗Element對象的方法和類,而無需手動調用javac。
- 1. 如何編寫異常處理的自動化測試
- 2. 如何編寫自動化腳本的單元測試?
- 3. 爲框架編寫測試註釋
- 4. Microsoft測試管理器如何運行自動單元測試?
- 5. 單元測試註釋?
- 6. 自定義註釋處理器 - Java
- 7. @SuppressWarnings來自Java註釋處理器
- 8. 編譯器如何處理註釋?
- 9. 爲單元測試自動化輸入
- 10. 如何編寫Java註釋處理程序?
- 11. 自定義註釋處理器 - 使用註釋檢測方法
- 12. 如何在Xcode中編寫GUI的自動單元測試?
- 13. 嘗試編寫Spring批處理單元測試時出現NoSuchBeanDefinitionException
- 14. 如何處理自動化測試中的超長定位器?
- 15. 如何爲Python socketserver請求處理程序編寫單元測試?
- 16. 爲單元測試編寫一個複雜的預處理器宏
- 17. 何時處理Java註釋?
- 18. 爲maven-processor-plugin編寫註釋處理器
- 19. 如何爲Play Framework JSON閱讀器編寫單元測試
- 20. Android&Robotium - 編寫自動化測試?
- 21. 爲Java自動化單元測試,一旦代碼改變
- 22. 如何在Gradle中使用自定義Java註釋處理器?
- 23. Java註釋處理器,帶註釋的註釋類型
- 24. 如何編寫單元測試
- 25. 如何編寫單元測試?
- 26. 如何編寫getPopularItems()的單元測試?
- 27. 如何編寫加密單元測試?
- 28. vue karma,如何編寫單元測試
- 29. 如何編寫「髒」單元測試?
- 30. 如何進行單元測試數據註釋驗證器