Exemple d'annotations personnalisées Java
Dans ce didacticiel, nous allons vous montrer comment créer deux annotations personnalisées -@Test
et@TestInfo
, pour simuler un cadre de test unitaire simple.
P.S This unit test example is inspired by this official Java annotation article.
1. Annotation @Test
Ce@interface
indique à Java qu'il s'agit d'une annotation personnalisée. Plus tard, vous pouvez l'annoter au niveau de la méthode comme ceci@Test(enable=false)
.
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
Les déclarations de méthode ne doivent pas avoir de paramètres ni de clause throws. Les types de retour sont limités aux primitives, chaîne, classe, énumérations, annotations et tableaux des types précédents.
2. Annotation @TesterInfo
Ce@TesterInfo
est appliqué au niveau de la classe, stockez les détails du testeur. Cela montre l'utilisation différente des types de retour - enum, array et 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. Exemple de test unitaire
Créez un exemple de test unitaire simple et annoté avec les nouvelles annotations personnalisées -@Test
et@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. Réflexion Java - Lire l'annotation
L'exemple ci-dessous vous montre comment utiliser les API de réflexion Java pour lire et traiter les annotations personnalisées.
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; Classobj = 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); } }
Sortie
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
Terminé.