java-custom-annotation、width = 244、height = 240

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

完了しました。