
このチュートリアルでは、簡単な単体テストフレームワークをシミュレートするために、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]