Maison  >  Article  >  Java  >  Utilisation de base et précautions pour les tests unitaires Junit

Utilisation de base et précautions pour les tests unitaires Junit

零下一度
零下一度original
2017-06-28 09:08:152464parcourir

Utilisation de base des tests unitaires Junit :
1. Ajouter une annotation @Test
sur la méthode à exécuter 2. L'annotation signalera une erreur et la solution est ctrl+1 add junit
3 . Sélectionnez la méthode à exécuter Cliquez avec le bouton droit sur la méthode et exécutez en tant que --> junit Test

Exécutez plusieurs méthodes à la fois : Faites un clic droit sur la classe sélectionnée et exécutez en tant que --> Junit Test<.>
Notes sur les tests unitaires Junit :
1. Les méthodes sans l'annotation @Test ne peuvent pas être exécutées avec Junit
2. Junit ne peut exécuter que des méthodes à paramètres vides avec le modificateur public et le type de valeur de retour void


Annotations liées aux tests unitaires

@Test : Test unitaire, vous pouvez exécuter une méthode séparément
@Avant : Exécuté avant le test unitaire @Test peut être utilisé pour obtenir certaines ressources
@After : Exécuté après le test unitaire @Test Peut être utilisé pour utiliser certaines ressources
Remarque : @Before et @After ne peuvent pas être exécutés séparément pour exécuter @Test, ils seront exécutés automatiquement

Annotations fournies après JDK1.5
@Obsolète : Indique qu'il est obsolète
@Obsolète : Il peut être utilisé pour modifier des classes pour représenter des classes obsolètes, et il peut également être utilisé pour modifier des méthodes pour représenter des méthodes obsolètes
Des classes et méthodes obsolètes peuvent être utilisées, mais ce n'est pas recommandé car elles peuvent présenter des défauts ou être meilleures La méthode remplace les annotations

fournies après JDK1.5
@Override : Une méthode utilisée pour tester si la méthode est remplacée
Dans JDK1.5, @Override ne peut détecter que l'héritage de classe et la réécriture de classe. Méthode
JDK1.6 et supérieur, @Override peut détecter à la fois la méthode de réécriture de classe d'héritage et la réécriture de l'interface d'implémentation de classe. méthode

Annotations fournies après JDK1.5
@SuppressWarnings : Indique la suppression des avertissements (ne permet pas l'affichage des avertissements)
@SuppressWarnings : Lorsque vous l'utilisez, vous devez être clair sur l'avertissement que vous souhaitez pour supprimer
@SuppressWarnings (paramètre) : Le paramètre est un tableau de chaînes
Si vous n'écrivez qu'un seul paramètre, {} peut être ignoré S'il y a plusieurs paramètres, {} doit être utilisé pour séparer plusieurs paramètres par des virgules <.> String[] a = {"ac","ds">
Les avertissements qui peuvent être supprimés sont :
rawtypes, ignorer la sécurité des types
décoché ignorer le contrôle de sécurité
inutilisé ignorer inutilisé
dépréciation ignorer obsolète
null ignorer le pointeur nul
série ignorer le numéro de série
tous ignorer tout
annotations Portée : peut être définie sur la méthode ou le code de la classe
La même annotation ne peut être utilisée qu'une seule fois à le même emplacement


Annotation personnalisée : utiliser le mot-clé @interface
pour définir la classe : class
Définir l'interface : interface
Définir l'énumération : enum (élimination)
Définir l'annotation : @interface
Définir le format de l'annotation :
Modifier @interface Nom de l'annotation {
Attributs annotés (peut être présent ou non)
Définir des annotations contenant des attributs :
Les attributs sont équivalents aux variables membres et aux méthodes membres dans les classes
Format de définition des attributs :
Type de valeur de retour du modificateur (type de données) Nom de l'attribut () [valeur de l'attribut par défaut]
Modificateur : format fixe (similaire à l'interface ) public abstract Il est recommandé d'écrire des lignes de lecture améliorées, que vous l'écriviez ou non
Type de valeur de retour : type de données de base (8 types dans 4 catégories) )Type de chaîne Annotation d'énumération de type de classe Tableau unidimensionnel du type ci-dessus
[valeur de l'attribut par défaut] : [] Les attributs facultatifs peuvent donner une valeur par défaut ou ne pas donner une valeur par défaut
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 }
Définir une annotation contenant des attributs
Cette annotation n'a qu'un seul attribut nommé value


Meta annotation : utilisée pour modifier les annotations personnalisées L'annotation fournie par le JDK
@Retention est utilisée pour déterminer la période de déclaration des annotations modifiées annotation personnalisée
L'attribut de l'annotation Retention est une énumération RetentionPolicy (l'énumération a 3 attributs SOURCE, CLASS, RUNTIME)
Fonction : Indique combien de temps le type d'annotation doit être conservé
S'il n'y a pas d'annotation Retention dans la déclaration du type d'annotation, la politique de rétention est par défaut RetentionPolicy.CLASS
RetentionPolicy.SOURCE Les annotations modifiées ne peuvent exister que dans le code source, pas les classes de bytecode. Objectif : Fourni au compilateur.
Les annotations modifiées RetentionPolicy.CLASS ne peuvent exister que dans le code source et le bytecode, pas dans la mémoire d'exécution. Objectif : la machine virtuelle Java JVM utilise
RetentionPolicy.RUNTIME. L'annotation modifiée existe dans le code source, le bytecode et la mémoire (runtime). Objectif : Remplacer la configuration XML
@Target est utilisé pour déterminer l'emplacement d'utilisation de l'annotation personnalisée modifiée
L'attribut de l'annotation Target est une énumération ElementType (attributs couramment utilisés TYPE, CONSTRUCTOR....)
Fonction : indique le type d'élément de programme auquel le type d'annotation s'applique.
Si aucune méta-annotation Target n'est présente dans la déclaration du type d'annotation, le type déclaré peut être utilisé sur n'importe quel élément du programme.
Classe modifiée ElementType.TYPE, interface
Structure modifiée ElementType.CONSTRUCTOR
Méthode modifiée ElementType.METHOD
Champ modifié ElementType.FIELD

使用自定义注解:
 格式:@自定义注解的名字(属性名= 属性值 ,属性名=属性值)
 注意:
 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 }

 

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn