Beispiel für benutzerdefinierte Java-Anmerkungen

Beispiel für benutzerdefinierte Java-Anmerkungen

java-custom-annotation

In diesem Tutorial zeigen wir Ihnen, wie Sie zwei benutzerdefinierte Anmerkungen erstellen -@Test und@TestInfo, um ein einfaches Unit-Test-Framework zu simulieren.

P.S This unit test example is inspired by this official Java annotation article.

1. @ Test Annotation

Dieses@interface teilt Java mit, dass dies eine benutzerdefinierte Anmerkung ist. Später können Sie es auf Methodenebene wie@Test(enable=false) mit Anmerkungen versehen.

Test.java

package com.example.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;

}

Note
Methodendeklarationen dürfen keine Parameter oder eine Throws-Klausel enthalten. Rückgabetypen sind auf Grundelemente, Zeichenfolgen, Klassen, Aufzählungen, Anmerkungen und Arrays der vorhergehenden Typen beschränkt.

2. @ TestInfo Annotation

Dieses@TesterInfo wird auf Klassenebene angewendet. Speichern Sie die Testdetails. Dies zeigt die unterschiedliche Verwendung von Rückgabetypen - Enum, Array und String.

TesterInfo.java

package com.example.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";

}

3. Unit Test Beispiel

Erstellen Sie ein einfaches Unit-Test-Beispiel und kommentieren Sie es mit den neuen benutzerdefinierten Annotationen -@Test und@TesterInfo.

TestExample.java

package com.example.test;

import com.example.test.core.Test;
import com.example.test.core.TesterInfo;
import com.example.test.core.TesterInfo.Priority;

@TesterInfo(
    priority = Priority.HIGH,
    createdBy = "example.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 Reflection - Lesen Sie die Anmerkung

Das folgende Beispiel zeigt Ihnen, wie Sie Java Reflection-APIs zum Lesen und Verarbeiten der benutzerdefinierten Anmerkungen verwenden.

RunTest.java

package com.example.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import com.example.test.core.Test;
import com.example.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 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);

    }
}

Ausgabe

Testing...

Priority :HIGH
CreatedBy :example.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

Erledigt.