Javaカスタムアノテーションの例
このチュートリアルでは、簡単な単体テストフレームワークをシミュレートするために、2つのカスタム注釈(@ Testと@ TestInfo)を作成する方法を説明します。
__P.Sこのユニットテストの例は、この公式のhttp://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html[Java注釈記事]に触発されています。
1. @Test Annotation
この `@interface`はJavaにカスタムアノテーションであることを伝えます。後で、 `@Test(enable = false)`のようにメソッドレベルで注釈を付けることができます。
Test.java
package com.mkyong.test.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)//can use in method only. public @interface Test { //should ignore this test? public boolean enabled() default true; }
戻り型は、プリミティブ、文字列、クラス、列挙型、注釈、および先行する型の配列に制限されています。
2. @TesterInfoアノテーション
この `@TesterInfo`はクラスレベルで適用され、テスターの詳細を格納します。
これは、戻り値の型(enum、array、string)の使い方を示しています。
TesterInfo.java
package com.mkyong.test.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE)//on class level public @interface TesterInfo { public enum Priority { LOW, MEDIUM, HIGH } Priority priority() default Priority.MEDIUM; String[]tags() default ""; String createdBy() default "Mkyong"; String lastModified() default "03/01/2014"; }
ユニットテストの例
単純な単体テストの例を作成し、新しいカスタム注釈 –
@ Test`と
@TesterInfo`で注釈を付けます。
TestExample.java
package com.mkyong.test; import com.mkyong.test.core.Test; import com.mkyong.test.core.TesterInfo; import com.mkyong.test.core.TesterInfo.Priority; @TesterInfo( priority = Priority.HIGH, createdBy = "mkyong.com", tags = {"sales","test" } ) public class TestExample { @Test void testA() { if (true) throw new RuntimeException("This test always failed"); } @Test(enabled = false) void testB() { if (false) throw new RuntimeException("This test always passed"); } @Test(enabled = true) void testC() { if (10 > 1) { //do nothing, this test always passed. } } }
4. Javaリフレクション – 注釈を読む
以下の例では、JavaリフレクションAPIを使用してカスタム注釈を読み込んで処理する方法を示します。
RunTest.java
package com.mkyong.test; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import com.mkyong.test.core.Test; import com.mkyong.test.core.TesterInfo; public class RunTest { public static void main(String[]args) throws Exception { System.out.println("Testing..."); int passed = 0, failed = 0, count = 0, ignore = 0; Class<TestExample> obj = TestExample.class; //Process @TesterInfo if (obj.isAnnotationPresent(TesterInfo.class)) { Annotation annotation = obj.getAnnotation(TesterInfo.class); TesterInfo testerInfo = (TesterInfo) annotation; System.out.printf("%nPriority :%s", testerInfo.priority()); System.out.printf("%nCreatedBy :%s", testerInfo.createdBy()); System.out.printf("%nTags :"); int tagLength = testerInfo.tags().length; for (String tag : testerInfo.tags()) { if (tagLength > 1) { System.out.print(tag + ", "); } else { System.out.print(tag); } tagLength--; } System.out.printf("%nLastModified :%s%n%n", testerInfo.lastModified()); } //Process @Test for (Method method : obj.getDeclaredMethods()) { //if method is annotated with @Test if (method.isAnnotationPresent(Test.class)) { Annotation annotation = method.getAnnotation(Test.class); Test test = (Test) annotation; //if enabled = true (default) if (test.enabled()) { try { method.invoke(obj.newInstance()); System.out.printf("%s - Test '%s' - passed %n", ++count, method.getName()); passed++; } catch (Throwable ex) { System.out.printf("%s - Test '%s' - failed: %s %n", ++count, method.getName(), ex.getCause()); failed++; } } else { System.out.printf("%s - Test '%s' - ignored%n", ++count, method.getName()); ignore++; } } } System.out.printf("%nResult : Total : %d, Passed: %d, Failed %d, Ignore %d%n", count, passed, failed, ignore); } }
出力
Testing... Priority :HIGH CreatedBy :mkyong.com Tags :sales, test LastModified :03/01/2014 1 - Test 'testA' - failed: java.lang.RuntimeException: This test always failed 2 - Test 'testC' - passed 3 - Test 'testB' - ignored Result : Total : 3, Passed: 1, Failed 1, Ignore 1
完了しました。
参考文献
-
http://en.wikipedia.org/wiki/Java__annotation
[Wikipedia:Java
JavaSEドキュメント – 注釈]。
http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/ElementType.html
[ElementType
JavaDoc]。
http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html
[RetentionPolicy
JavaDoc]