溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JAVA中如何自定義一個@Test注解呢?

發(fā)布時間:2020-07-21 23:15:26 來源:網(wǎng)絡 閱讀:554 作者:專注地一哥 欄目:編程語言

相信用過 Junit 的朋友都知道 JUnit是Java的一個單元測試框架,在實現(xiàn)自動單元測試的情況下可以大大的提高開發(fā)的效率,那么我們如何自定義一個@Test注解呢?首先,我們先寫一個@Test注解,如下:
br/>首先,我們先寫一個@Test注解,如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**

  • @author Woo_home
  • @create by 2019/9/18*/
    @Retention(RetentionPolicy.RUNTIME)
    br/>*/
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {}
    @Test注解類型的聲明就是它自身通過Retention和Target注解進行了注解。注解類型聲明中的這種注解被稱為元注解(meta-annotation)。@Retention(RetentionPolicy.RUNTIME)元注解表明,@Test注解應該在運行時保留。如果沒有保留,測試工具就無法知道@Test注解。@Target(ElementType.METHOD)元注解表明,@Test注解只在方法聲明中才是合法的:它不能運用到類聲明。域聲明或者其他程序元素上
    br/>}
    @Test注解類型的聲明就是它自身通過Retention和Target注解進行了注解。注解類型聲明中的這種注解被稱為元注解(meta-annotation)。@Retention(RetentionPolicy.RUNTIME)元注解表明,@Test注解應該在運行時保留。如果沒有保留,測試工具就無法知道@Test注解。@Target(ElementType.METHOD)元注解表明,@Test注解只在方法聲明中才是合法的:它不能運用到類聲明。域聲明或者其他程序元素上
    package demo;
    import annotation.Test;
    /**
  • @author Woo_home
  • @create by 2019/9/18
    */
    public class TestDemo {@Test
    br/>@Test
    System.out.println("Hello World");
    }
    }
    編寫測試運行類
    package utils;
    import annotation.Test;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    /**
  • @author Woo_home
  • @create by 2019/9/18
    */
    public class RunTests {
    public static void main(String[] args) throws Exception{
    int tests = 0; //記錄成功
    int passed = 0;//記錄失敗
    Class testClass = Class.forName("demo.TestDemo"); //反射帶有@Test注解的類
    for (Method m : testClass.getDeclaredMethods()) {
    if (m.isAnnotationPresent(Test.class)){ //Test是定義的注解類,isAnnotationPresent方法告知該工具運行哪些方法
    tests++;
    try {
    m.invoke(testClass.newInstance()); //通過調用invoke反射式地運行類中所有標注了@Test的方法
    passed++;
    }catch (InvocationTargetException wrappedExc){
    Throwable exc = wrappedExc.getCause();
    System.out.println(m + " failed: " + exc);
    }catch (Exception exc){
    System.out.println("INVALID @Test: " + m);
    }
    }
    }
    System.out.printf("Passed: %d, Failed: %d%n",tests,tests-passed);}
    }
    我們運行這個類就會打印出標注有@Test注解的方法
    br/>}
    }
    我們運行這個類就會打印出標注有@Test注解的方法
    package demo;
    import annotation.Test;
    /**
  • @author Woo_home
  • @create by 2019/9/18
    */
    public class TestDemo {@Test
    br/>@Test
    i = 0;
    return i;}
    @Test
    br/>}
    @Test
    System.out.println("Hello World");
    }
    }
    案例
    首先是一個空的注解類MyTest.java? :
    package com.iceflame.mytest;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)
    br/>@Retention(RetentionPolicy.RUNTIME)
    然后是一個util類,里面的方法加上@MyTest注解
    br/>}
    然后是一個util類,里面的方法加上@MyTest注解
    public class StringUtil {@MyTest
    br/>@MyTest
    public void print()
    {
    System.out.println("print()方法執(zhí)行了");
    }
    }
    最后是核心運行類,coreRunner.java(主要是用反射的思想,取出加了注解的方法并執(zhí)行)
    package com.iceflame.mytest;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    public class CoreRunner {
    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, ClassNotFoundException {
    // Class clazz=Class.forName("com.iceflame.mytest.StringUtil");
    Class clazz=StringUtil.class;
    Method [] methods=clazz.getMethods();
    for(Method m:methods)
    {
    if(m.isAnnotationPresent(MyTest.class))
    {
    m.invoke(clazz.newInstance(),null);
    }
    }
    }
    }
    需要注意的是,m.invoke(***,null) 這里的null是參數(shù),也就是方法執(zhí)行的參數(shù),我們這里利用反射是不知道參數(shù)的,所以也能解釋為什么我們用@Test的時候,加注解的方法一般都沒有參數(shù),因為方法是靜態(tài)的,而參數(shù)是動態(tài)的,在運行的時候傳過來,我們現(xiàn)在只是利用反射,反向實例化一個類,然后執(zhí)行里面的某一個無參方法。使用自定義注解完成@Test注解功能類似的效果
    br/>使用自定義注解完成@Test注解功能類似的效果
    使用Junit是單元測試的工具,在一個類中使用@Test對程序的方法進行測試,自定義一個注解@MyTest 也將這個注解加在類的方法上,是這個方法得到執(zhí)行。
    1. 技術分析:
      【注解】
      程序中有注釋和注解
      注釋:給開發(fā)人員看.
      注解:給計算機看的.
      【JDK提供的注釋】
      @override :描述方法的重寫.
      @SupperssWarnings :壓制警告.
      @Deprecated ?:標記過時.【自定義注解】
      定義一個類:class
      定義一個接口:interface
      定義一個枚舉:enum
      定義一個注解:@interface
      br/>【自定義注解】
      定義一個類:class
      定義一個接口:interface
      定義一個枚舉:enum
      定義一個注解:@interface
      @interface MyDemo1{
      }
      帶有屬性的注解:
      @interface MyDemo2{
      int a()default 1;
      String b( );
      // 注解屬性的類型:基本數(shù)據(jù)類型,字符串類型Sti讓你過,Class,注解類型,枚舉類型,以及以上類型的一維數(shù)組。
      // Date 的();
      Class cl();
      MyDemo3 D3(); //注解
      Color c(); //枚舉
      String[ ] arrs( );
      }
      @MyDemo4("aaa") // ?如果屬性名稱為value那么使用得時候value可以省略(值出現(xiàn)value得屬性情況下).
      public ?class ?Demo3{

      @interface ?MyDemo4{
      String ? value;
      int ?a( ) default 1;

      3、步驟分析
      定義一個測試類:
      public class Demo3{@MyTest
      br/>@MyTest
      System.out.println("demo1 執(zhí)行了。。。。");

      public void ? ??demo2( ){System.out.println("demo2執(zhí)行了。。。。");
      }

      定義核心運行類:
      在核心運行類中有一個主函數(shù)。
      獲得測試類的所有方法。
      獲得每個方法,查看方法上是否有@MyTest注解。
      br/>System.out.println("demo2執(zhí)行了。。。。");
      }

      定義核心運行類:
      在核心運行類中有一個主函數(shù)。
      獲得測試類的所有方法。
      獲得每個方法,查看方法上是否有@MyTest注解。
      4、代碼實現(xiàn)
      通過元注解定義注解存在的階段
      定義一個注解:
      核心運行類:
      public ? class ?Runner{
      public ?static ?void ? main (String ?[ ?] ?args){
      //反射:獲取類得字節(jié)碼對象.class
      Class ? ?class1=Demo3.class;
      //獲取測試類中得所有方法:
      Method[ ?] ? mjethods= class.getMethods();
      // ?遍歷數(shù)組:
      for( Method ? ?method ?: ? methods){
      //System.out.println( method .getName() ) ;//判斷方法是否有@MyTest注解:
      br/>//判斷方法是否有@MyTest注解:
      // System.out.println(method.getName()+"?? "+flag);
      ??? ??? ??? if(flag){
      ??? ??? ??? ??? // 讓這個方法執(zhí)行:
      ??? ??? ??? ??? try {
      ??? ??? ??? ??? ??? method.invoke(clazz.newInstance(),null);
      ??? ??? ??? ??? } catch (Exception e) {
      ??? ??? ??? ??? ??? e.printStackTrace();
      ??? ??? ??? ??? }
      ??? ??? ??? }
      ??? ??? }
      ??? }
      }
      使用注解完成JDBC工具的編寫:
      public class JDBCUtils {
      ??? privatestatic? String driverClass;
      ??? privatestatic? String url;
      ??? privatestatic? String username;
      ??? privatestatic? String password;
      ??? @JDBCInfo
      ??? publicstatic Connection getConnection() throws Exception{
      ??? ??? // 反射:
      ??? ??? Class clazz = JDBCUtils.class;
      ??? ??? Method method =clazz.getMethod("getConnection", null);
      ??? ??? // 獲得方法上的注解:
      ??? ??? JDBCInfo jdbcInfo =method.getAnnotation(JDBCInfo.class);
      ??? ??? driverClass =jdbcInfo.driverClass();
      ??? ??? url = jdbcInfo.url();
      ??? ??? username = jdbcInfo.username();
      ??? ??? password = jdbcInfo.password();
      ??? ????? ??? Class.forName(driverClass);
      ??? ??? Connection conn =DriverManager.getConnection(url, username, password);
      ??? ??? return conn;
      ??? }
      }
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI