首頁  >  文章  >  Java  >  Junit單元測試的基本使用與注意事項

Junit單元測試的基本使用與注意事項

零下一度
零下一度原創
2017-06-28 09:08:152479瀏覽

Junit單元測試的基本使用:
 1.在要執行的方法上加入一個註解@Test
 2.註解會錯誤解決方式ctrl+1 add junit
 3.選取要執行的方法右鍵run as --> junit Test

 一次執行多個方法:選取類別右鍵run as --> Junit Test

 Junit單元測試的注意事項:
 1 .沒有加入@Test註解的方法不能使用Junit運行
 2.Junit只能運行修飾符為public 返回值類型為void 的空參數方法


 和單元測試有關的註解

 @Test:單元測試,可以單獨的執行某個方法
 @Before:在單元測試@Test之前執行可以用來取得一些資源
 @After:在單元測試@Test之後執行可以用來使用一些資源
 注意:@Before和@After不能單獨執行運行@Test他們會自動執行

 JDK1.5之後提供的註解
 @Deprecated:表示已經過時的
 @Deprecated:可以用來修飾類別表示已經過時的類別,也可以用來修飾方法表示已經過時的方法
 已經過時的類別和方法可以使用但是不建議因為可能存在缺陷或者被更好的方法取代了

JDK1.5之後提供的註解
 @Override:用來測試方法是否為重寫的方法
 JDK1.5時@Override只能偵測類別繼承類別重寫的方法
 JDK1.6以上,@Override即能偵測類別繼承類別重寫的方法又能偵測類別實作介面重寫的方法

JDK1.5之後提供的註解
 @SuppressWarnings :表示抑制警告(不讓警告顯示出來)
 @SuppressWarnings:使用時必須明確要抑制的是哪個警告
 @SuppressWarnings(參數):參數是一個字串數組
 如果只寫一個參數可以忽略{} 如果有多個參數必須使用{}多個參數之間使用逗號隔開
 String[]  a = {"ac","ds"}
 可以抑制的警告有:
 rawtypes, 忽略型別安全
 unchecked 忽略安全檢查
 unused 忽略不使用
 deprecation 忽略過時
 null 忽略空指標
 serial 忽略序號
 null 忽略空指標
 serial 忽略序號
的作用域:可以定義在類別上方法上程式碼上
 同一個位置只能使用一次同一個註解


自訂註解:使用關鍵字@interface
 定義類別: class
 定義介面:interface
 定義枚舉:enum(淘汰)
 定義註解:@interface
 定義註解的格式:
 修飾符@interface 註解名{
   註解的屬性;(可以沒有)
 定義含有屬性的註解:
 屬性相當於類別中的成員變數成員方法
 屬性的定義格式:
 修飾子回傳值類型(資料型別)屬性名()[default 屬性值]
  修飾符:固定的格式(類似介面) public abstract  寫不寫都是建議寫出增強閱讀行
  回傳值類型:基本資料型別(4類8種)String 類型Class類型枚舉註解以上類型的一維數組
  [default 屬性值]:[]可選的屬性可以給出預設值也可以不給預設值

   int a; int a = 10 ;
 1 public @interface MyAnnotation02 { 2     //基本数据类型(4类8种) 3     public abstract int a() default 10; 4     //String类型 5     public abstract String s(); 6     //Class类型 7     public abstract Class clazz(); 8     //枚举 9     public abstract Color c();10     //注解11     public abstract MyAnnotation01 myanno01();12     //以上类型的一维数组13     public abstract String[] arr();14 }15 16 enum Color{17     GREEN,18     RED19     /*20      * public static final Color GREEN = new Color();21      * public static final Color RED = new Color();22      */23 }


定義一個含有屬性的註解
 這個註解只有一個屬性屬性的名字叫value

 元註解:用來修飾自訂註解的JDK提供的註解
 @Retention  用於確定被修飾的自訂註解聲明週期
 Retention 註解的屬性是一個枚舉RetentionPolicy(枚舉有3個屬性SOURCE,CLASS,RUNTIME)
# 作用:指示指示註解類型的註解要保留多久
   如果註解類型宣告中不存在Retention註解則保留原則預設為RetentionPolicy.CLASS
   RetentionPolicy.SOURCE 被修飾的註解只能存在原始碼中,字節碼class沒有。用途:提供給編譯器使用。
RetentionPolicy.CLASS 被修飾的註解只能存在源碼和字節碼中,運行時記憶體中沒有。用途:JVM java虛擬機器使用
RetentionPolicy.RUNTIME 被修飾的註解存在源碼、字節碼、記憶體(運行時)。用途:取代xml配置
@Target 用來決定被修飾的自訂註解使用位置
Target註解的屬性是一個列舉ElementType(常用的屬性TYPE,CONSTRUCTOR....)
作用:指示註解類型所適用的程式元素的種類。
如果註釋類型宣告中不存在 Target 元註釋,則宣告的型別可以用在任一程式元素上。
ElementType.TYPE 修飾類別、介面
ElementType.CONSTRUCTOR  修飾建構
ElementType.METHOD 修飾方法

ElementType.FIELD 修飾欄位
1 @Retention(RetentionPolicy.RUNTIME)2 @Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})3 public @interface MyAnnotation03 {4     public abstract int value();5 }
###

使用自定义注解:
 格式:@自定义注解的名字(属性名= 属性值 ,属性名=属性值)
 注意:
 1.自定义注解没有属性,可以直接使用-->@自定义注解的名字
 2.自定义注解有属性 使用的时候 必须使用键值对的方式 给所有属性赋值 才能使用 有默认值的属性可以不用赋值
 3.如果注释的属性是一个数组 赋值的时候只有一个值可以省略{} 赋值多个必须写出{}
 4.注解的使用范围  可以用来修饰类 方法 构造方法 变量
 5.使用自定义注解 如果只有一个属性 名字叫value 赋值的时候value可以省略不写
 6.一个对象上(修饰类, 方法,构造方法,变量)注解只能使用一次 不能重复使用

自定义注解的解析:使用自定义注解 获取自定义注解的属性值
 和解析有关的接口:
 java.lang.reflect.AnnotatedElement接口
 所有已知实现类:AccessibleObject Class Constructor Field Method Package
 接口中的方法:
  boolean isAnnotationPresent(Class annotationClass)
  如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
  判断(Constructor, Field, Method...)有没有指定的注解
  参数:注解的class文件对象,可以传递MyAnnotation03.class(String.class,int.class)
  T getAnnotation(Class annotationClass)
  如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
  获取(Constructor, Field, Method...)上的注解,参数传递的是哪个注解的class文件对象,就获取哪个注解
  参数:注解的class文件对象,可以传递MyAnnotation03.class


 使用步骤:
  1.定义一个方法,使用自定义注解
  2.使用反射技术获取本类的class文件对象
  3.使用反射技术获取类中所有的方法
  4.遍历包含所有方法的数组,获取每一个方法
  5.使用isAnnotationPresent判断该方法上是否包含传递参数的注解
  6.如果方法上包含注解,使用getAnnotation获取方法上的注解
  7.使用属性的名字,获取属性值

 1 public class UseMyAnnotation02 { 2     //1.定义一个方法,使用自定义注解 3     @MyAnnotation03(value=10) 4     public void method(){ 5          6     } 7      8     @Test 9     public void test(){10         //2.使用反射技术获取本类的class文件对象11         Class clazz = UseMyAnnotation02.class;12         //3.使用反射技术获取类中所有的方法13         Method[] methods = clazz.getMethods();14         //4.遍历包含所有方法的数组,获取每一个方法15         for (Method method : methods) {16             String methodName = method.getName();17             //5.使用isAnnotationPresent判断该方法上是否包含传递参数的注解18             boolean b = method.isAnnotationPresent(MyAnnotation03.class);19             if(b){20                 System.out.println(methodName+":"+b);21                 //6.如果方法上包含注解,使用getAnnotation获取方法上的注解22                 MyAnnotation03 myAnno = method.getAnnotation(MyAnnotation03.class);23                 //7.使用属性的名字,获取属性值24                 int v = myAnno.value();25                 System.out.println(v);26             }27         }28     }29 }

类加载器:把class文件加载到内存中 并生成一个class文件对象

加载器的组成:
Bootstrap ClassLoader 引导(根)类加载器
 也被称为引导类加载器 负责java核心类的加载
 Extension ClassLoader 扩展类加载器
 负责人JRE的扩展目录中的jar包的加载
 在JDK中JRE的lib目录下井ext目录
 AppClassLoader 应用类加载器
  负责在JVM启动时加载来自java命令的class文件 以及classpath环境变量
  所指定的jar包和类路径
  自定义的类型Person; commons-io-2.4.jar
类加载器的继承关系:
AppClassLoader extends ExtClassLoader extends Bootstrap ClassLoader extends ClassLoader
和类加载器有关的方法:
Class类中的方法:
ClassLoader getClassLoader() 返回该类的类加载器。
ClassLoader类中的方法:
ClassLoader getParent() 返回委托的父类加载器。

 1 public class DemoClassLoader { 2     @Test 3     public void show01(){ 4         //获取应用类加载器 5         ClassLoader loader = DemoClassLoader.class.getClassLoader(); 6         System.out.println(loader);//sun.misc.Launcher$AppClassLoader@5fcf29 7          8         loader = loader.getParent(); 9         System.out.println(loader);//sun.misc.Launcher$ExtClassLoader@5fcf2910         11         loader = loader.getParent();12         System.out.println(loader);//根类加载器由c/c++编写,没有相关的类描述,返回null13     }14     15     @Test16     public void app(){17         //获取应用类加载器18         ClassLoader loader = DemoClassLoader.class.getClassLoader();19         System.out.println(loader);//sun.misc.Launcher$AppClassLoader@5fcf2920     }21     22     @Test23     public void ext(){24         //获取扩展类加载器25         /*26          * 扩展包中的类,不支持使用27          * 想使用必须设置访问权限28          * sun/**29          */30         ClassLoader loader = SunEC.class.getClassLoader();31         System.out.println(loader);//sun.misc.Launcher$ExtClassLoader@19b1de32     }33     34     @Test35     public void boot(){36         ClassLoader loader = String.class.getClassLoader();37         System.out.println(loader);//null38     }39 }

JDK动态代理:只能代理接口
 java.util.collections集合的工具类
 Collections集合的工具类的静态方法
 static List unmodifiableList(List list)
 返回指定列表的不可修改视图
 传递一个List集合返回一个被代理的List集合
 unmodifiableList方法就是一个代理方法,代理List集合
 如果调用size get方法 没有对集合进行修改 则允许执行
 如果调用add remove set 对集合进行了修改,则抛出异常不让方法执行
  会抛出UnsupportedOperationException:不支持操作异常

 1 public class Demo01Proxy { 2     @Test 3     public void show(){ 4         List<String> list = new ArrayList<String>(); 5         list.add("a"); 6         list.add("b"); 7          8         //调用Collections中的方法unmodifiableList 9         list = Collections.unmodifiableList(list);10         String s = list.get(0);11         System.out.println(s);12         13         System.out.println(list.size());14         15         //list.add("c");16         //list.remove(0);17     }18 }

创建接口InvocationHandler的实现类
 重写接口中的方法invoke 对集合的方法进行判断
 如果调用size get方法 没有对集合进行修改 则允许执行
 如果调用add remove set 对集合进行了修改 则抛出异常不让方法执行
 Object invoke(Object proxy,Method method,Object[] args)在代理实例上处理方法调用并返回结果
 参数:
  Object proxy:内部会使用反射创建一个代理人对象,和我们无关
Method method:内部会使用反射获取到执行List集合的方法(size,get,....)
  Object[] args:内部会使用反射获取到调用集合方法的参数
  返回值:
  Object:调用List集合的方法的返回值

  注意事项:
  代理的是List集合,必须把被代理的集合传递到实现类中,为了保证代理的始终是同一个List集合
  在成员位置创建一个List集合
  使用带参数构造给集合赋值

 1 public class InvocationHandlerImpl implements InvocationHandler{ 2     private List<String> list;   
 public InvocationHandlerImpl(List<String> list) { 5         
 this.list = list; 6     } 7  8     @Override 9     
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {10         
 //获取方法的名字11         String mehtodName = method.getName();12         
 //对方法的名字进行判断,如果是add,remove,set就抛出异常13         
 if("add".equals(mehtodName)){14             throw new UnsupportedOperationException("add no run");15         }   
 if("remove".equals(mehtodName)){18             throw new UnsupportedOperationException("remove no run");19         }     
 if("set".equals(mehtodName)){22             throw new UnsupportedOperationException("set no run");23         }        
 //如果是size,get执行方法25         Object obj = method.invoke(list, args);26         return obj;27     }
 }
 1 /* 2  * 动态代理综合案例: 3  * 需求: 4  *     模拟Collections.unmodifiableList(list); 5  *         传递List,返回List 6  *         调用List方法的时候,通过我的代理类中的方法 invoke, 7  *         如果调用size,get方法,没有对集合进行修改,则允许执行 8  *         如果调用add,remove,set,对集合进行了修改,则抛出异常不让方法执行 9  *             会抛出UnsupportedOperationException:不支持操作异常10  * 实现步骤:11  *     1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合12  *     2.在proxyList方法内部实现动态代理13  *         java.lang.reflect.Proxy:提供了和动态代理有关的方法14  *         static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
15  *             返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 
16  *         参数:17  *             ClassLoader loader:传递类加载器,加载类到内存中,创建class文件对象;可以传递本类的类加载器18  *             Class<?>[] interfaces:传递ArrayList实现的接口List/Collection的Class文件对象19  *             InvocationHandler h:创建一个InvocationHandler的实现类,重写接口中的方法invoke,对集合的方法进行判断20  *                 如果调用size,get方法,没有对集合进行修改,则允许执行21  *                 如果调用add,remove,set,对集合进行了修改,则抛出异常不让方法执行22  *         返回值类型:23  *             Object:返回被代理后的List集合24  
*/25 @SuppressWarnings("all")26 public class Demo02Proxy {27     /*28      * 1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合29      */30     public static List<String> proxyList(List<String> list){31         //2.在proxyList方法内部实现动态代理,调用Proxy类中的方法newProxyInstance32         List<String> proxyList = (List<String>) Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(),33                 list.getClass().getInterfaces(), new InvocationHandlerImpl(list));34         return proxyList;35     }   
/*      * 1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合39      */40     public static List<String> proxyList02(final List<String> list){41         //2.在proxyList方法内部实现动态代理,调用Proxy类中的方法newProxyInstance42         List<String> proxyList = (List<String>) Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(),43                 list.getClass().getInterfaces(), new InvocationHandler() {44                     @Override45                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {46                         
//获取方法的名字47                         
String mehtodName = method.getName();48                         //对方法的名字进行判断,如果是add,remove,set就抛出异常49                         if("add".equals(mehtodName)){50                             throw new UnsupportedOperationException("add no run");51                         }52                         53                         if("remove".equals(mehtodName)){54                             throw new UnsupportedOperationException("remove no run");55                         
}   
if("set".equals(mehtodName)){58                             throw new UnsupportedOperationException("set no run");59                         }60                         //如果是size,get执行方法61                         Object obj = method.invoke(list, args);62                         return obj;63                     }64                 });65         return proxyList;66     }67     68     @Test69     public void test(){70         List<String> list = new ArrayList<String>();71         list.add("a");72         list.add("b");73         //调用代理方法proxyList传递list集合74         
//list = Collections.unmodifiableList(list);75         
list = Demo02Proxy.proxyList(list);76         System.out.println(list.size());77         System.out.println(list.get(0));78         //list.add("c");//UnsupportedOperationException:add no run79         //list.remove(0);//UnsupportedOperationException:remove no run80         list.set(0, "c");//UnsupportedOperationException:set no run81     }82 }

 

以上是Junit單元測試的基本使用與注意事項的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn