zoukankan      html  css  js  c++  java
  • JavaWeb

    1.Junit白盒测试

      *步骤:

        1.定义一个测试类(测试用例)

          *建议:

            *测试类名:被测试的类名+Test

            *包名:xxx.xxx.xxx.test     cn.itcast.test

        2.定义测试方法:可以独立运行

          *建议:

            *方法名:test+测试的方法名  testAdd()

            *返回值:void 

            *参数列表:建议空参

        3.给方法加@Test

        4.导入Junit依赖环境 

        判定结果:

          *红色:失败

          *绿色:成功

          *一般我们会使用assert断言操作来处理结果

            Assert.assertEquals(期望值,真实值)进行比对

    public class CalculatorTest {
        /*
            测试add方法
        */
    
        @Test
        public void testAdd(){
            //System.out.println("我被执行了");
            /*
            * 1.创建计算器对象
            * 2.调用add方法
            * */
            Calculator c = new Calculator();
            int result = c.add(1, 2);
            System.out.println(result);  //无意义,如果是写成了减法依旧测试成功
    
            //3.断言 结果为3
            Assert.assertEquals(4,result);
        }
    }

     资源申请与资源释放:(@Before 和 @After)

    public class CalculatorTest {
        /*
        * 初始化方法
        *  用于资源申请,所有测试方法在执行之前都会先执行该方法
        * */
        @Before
        public void init(){
            System.out.println("init...已被执行");
        }
        /*
        * 释放资源的方法
        *   在所有测试方法执行完后都会自动执行该方法
        * */
        @After
        public void close(){
            System.out.println("close");
        }
    }

     2.反射:框架设计的灵魂

      *框架:半成品软件。可以在框架的基础上进行软件开发,简化编码

      *将类的各个组成部分封装成为其他对象,这就是反射机制

        *好处:

          1.可以在程序运行过程中,操作这些对象。

          2.可以解耦,来提高程序的可扩展性

    获取Class对象的方式:  

      1.Class.forName("全类名"): 将字节码文件加载进内存,返回Class对象

        *多用于配置文件,将类名定义在配置文件中。读取文件加载类

      2.类名.class:通过类名的属性class获取

        *多用于参数的传递

      3.对象.getClass():getClass()方法在Object类中定义着

        *多用于对象的一个获取字节码的方式

    public class DemoReflect {
        public static void main(String[] args) throws Exception {
            //第一种方式 Class.forName  
            Class cls1 = Class.forName("basicpart.day01.FaceObj.Zi");
            System.out.println(cls1);
    
            //第二种方式 类名.class
            Class cls2 = Zi.class;
            System.out.println(cls2);
    
            //第三种方式 对象.getClass
            Zi zi = new Zi();
            Class cls3 = zi.getClass();
            System.out.println(cls3);
    
            System.out.println(cls1==cls2);
        }
    }

      结论:

        同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过那一种方式获取的class文件只有一个

    3.Class对象的功能

      获取功能:

        1.获取成员变量们

        操作:Field成员变量

              1.设置值 void set(Object obj,Object value)

              2.获取值 get(Object obj)

          *Field【】  getFields():获取所有public修饰的成员变量

          *Field【】  getField(String name):获取指定名称的public修饰的成员变量

    public class DemoReflect {
        public static void main(String[] args) throws Exception {
            //获取一个字节码对象
            Class<Person> personClass = Person.class;
            //获取指定的成员变量对象
            Field field = personClass.getField("name");
    
            //创建一个对象
            Person p  = new Person();
            //获取值
            Object value = field.get(p);
            System.out.println(value);
    
            //设置值
            field.set(p,"chris");
            System.out.println(p);
    
        }
    }

          *Field【】  getDeclaredFields():获取所有的成员变量,不考虑权限修饰符

          *Field【】  getDeclaredField(String name)在访问之前要先忽略访问权限修饰符 暴力反射 setAccessible(true)

            Field age = personClass.getDeclaredField("age");
            //在访问之前需要先忽略权限访问修饰符
            age.setAccessible(true);//暴力反射
            Object value2 = age.get(p);
            System.out.println(value2);            

             

        2.获取构造方法们

          *Constructor<?>【】 getConstructors()

          *Constructor<T>【】 getConstructor(类<?>...parameterTypes)

     

          *Constructor<T>【】 getDeclaredConstructor(类<?>...parameterTypes)

          *Constructor<?>【】 getDeclaredConstructors()

          *Constructor用于创造对象  newInstance()方法 

            如果使用空参数构造方法创建对象,操作可以简化:Class对象有个newInstance()方法

    public class Demo2 {
        public static void main(String[] args) throws Exception {
            //构造器的使用
            Class<Person> personClass = Person.class;
            Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
    
            //创建对象
            Person chris = constructor.newInstance("chris", 21);
            System.out.println(chris);
            
            //空参创建
            Person person = personClass.newInstance();
        }
    }

        3.获取成员方法们

          *Method【】 getMethods()

          *Method【】 getMethod(String name,类<?>...parameterTypes)

     

          *Method【】 getDeclaredMethods()

          *Method【】 getDeclaredMethod(String name,类<?>...parameterTypes)

          *方法对象的功能:*执行方法 Object invoke(Object obj,Object...args)

                   *获取方法名  String getName();

    public class Demo2 {
        public static void main(String[] args) throws Exception {
            Class<Person> personClass = Person.class;
            //获取方法对象
            Method eat_method = personClass.getMethod("eat");
            //执行无参方法
            //先创建确定的对象
            Person p = new Person();
            eat_method.invoke(p);
    
            //执行有参的fangfa
            Method eat_method2 = personClass.getMethod("eat", String.class);
            eat_method2.invoke(p,"苹果");
    
        }
    }

        4.获取类名

          *String getName()

     

    案例:不能改变该类的任何代码,可以创建任意类的对象,执行任意方法

    /*
    * 框架类
    * */
    public class DemoStruct {
        public static void main(String[] args) throws Exception {
            //可以创建任意类的对象,可以执行任意方法
    
            /*
                不能改变该类的任何代码,可以创建任意类的对象,执行任意方法
            */
            //1.加载配置文件
            //1.1创建Properties对象
            Properties pro = new Properties();
            //1.2加载配置文件,转换为一个集合
            //1.2.1获取class目录下的配置文件
            ClassLoader classLoader = DemoStruct.class.getClassLoader();//获取该字节码文件的类加载器
            InputStream is = classLoader.getResourceAsStream("pro.properties");
            pro.load(is);
    
            //2.获取配置文件中定义的数据
            String className = pro.getProperty("className");
            String methodName = pro.getProperty("methodName");
    
            //3.加载该类进内存
            Class cls = Class.forName(className);
    
            //4.创建对象
            Object obj = cls.newInstance();
    
            //5.获取方法对象
            Method method = cls.getMethod(methodName);
    
            //6.执行方法
            method.invoke(obj);
        }
    }

    4.注解

    /**
     *  javadoc文档    
     * @author chris
     * @since jdk1.5
     * @version 1.0
     */
    public class annotation {
    
        /**
         * 文档注释
         * @param a 整数
         * @param b 整数
         * @return 两数的和
         */
        public int add(int a , int b){
            return a + b ;
        }
    }

    JDK内置注解

      1.限定父类重写方法:@Override  - 检测该注解标注的方法是否是继承自父类(接口)的

      2.标示已过时:@Deprecated - 将该注解标注的内容,表示已过时

      3.抑制编译器警告:@SuppressWarnings - 压制警告的  一般传递参数all

    @SuppressWarnings("all")  //压制了该类右侧的所有警告
    public class annoDemo2 {
        @Override
        public String toString() {
            return super.toString();
        }
    
        @Deprecated
        public void show1(){
            //有缺陷
        }
        public void show2(){
            //替代show1方法
        }
    }

    自定义注解:

      (1)*格式:

        *元注解  -  用于描述注解的注解

          (1)@Target:描述注解能够作用的位置

              ElementType取值:1.TYPE 类上  2. METHOD 方法上 3.FIELD 成员变量上 

              @Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})

          (2)@Retention:描述注解被保留的阶段  (源码,class,runtime)

              @Retention(RetentionPolicy.RUNTIME) 该注解会保留到class字节码文件中,并被JVM读取到

          (3)@Documented:描述注解是否被抽取到api文档

              @Documented

          (4)@Inherited:描述注解是否被子类继承

        *public @interface 注解名称{

              属性列表;  

              }

      (2)*本质:注解本质上就是一个接口,该接口默认继承Annotation接口

        *public interface MyAnno extends java.lang.annotation.Annotation { }

      (3)*属性:接口中的抽象方法

        *要求:

          1.属性的返回值类型

            *基本数据类型

            *字符串String

            *枚举

            *注解

            *以上类型的数组

          2.定义了属性,在使用时需要给属性赋值 @MyAnno(show = "cc")   也可在注解里 default 设置默认值 

            如果只有一个属性需要赋值,而且属性的名称是value,则value可以省略

            数组赋值时,值使用{ }包裹。如果数组中只有一个值,则{ }可以省略

     

    *在程序中使用(解析)注解:获取注解中定义的属性值

      1.获取注解定义位置的对象,定义在类上就获取类,定义在方法上就获取方法 (Class,Method,Field)

      2.获取指定的注解对象  getAnnotation(xxx.class)

        其实就是在内存中生成了该注解接口的子类实现对象,方法中的返回值就是刚刚定义的值

      3.调用注解中的抽象方法获取配置的属性值

    /*
    * 框架类
    * */
    @ProAnno(ClassName = "JavaWeb.reflect.Person", MethodName = "eat")
    public class AnnoComple {
        public static void main(String[] args) throws Exception {
            //可以创建任意类的对象,可以执行任意方法
    
            /*
                不能改变该类的任何代码,可以创建任意类的对象,执行任意方法
            */
    
            //1.解析注解
                //1.1获取注解定义的该类的字节码文件对象 本类
            Class<AnnoComple> annoCompleClass = AnnoComple.class;
    
            //2.获取上边的注解对象
            //其实就是在内存中生成了该注解接口的子类实现对象,方法中的返回值就是刚刚定义的值
            ProAnno an = annoCompleClass.getAnnotation(ProAnno.class);
    
            //3.调用注解对象定义的抽象方法来获取返回值
            String className = an.ClassName();
            String methodName = an.MethodName();
    
            System.out.println(className);
            System.out.println(methodName);
    
            //3.加载该类进内存
            Class cls = Class.forName(className);
    
            //4.创建对象
            Object obj = cls.newInstance();
    
            //5.获取方法对象
            Method method = cls.getMethod(methodName);
    
            //6.执行方法
            method.invoke(obj);
        }
    }

    测试框架案例:

      check注解:

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Check {
    }

      测试框架:

    /*
        简单的测试框架
        当主方法执行后,会自动执行被检测的所有方法(加了check注解的方法),判断方法是否有异常,记录到文件中
    */
    public class TestCheck {
        public static void main(String[] args) throws IOException {
            //1.创建计算器对象
            Calculator c = new Calculator();
    
            //2.获取字节码文件对象
            Class cls = c.getClass();
    
            //3.获取所有方法
            Method[] methods = cls.getMethods();
    
            int number = 0; //记录异常的次数
    
            BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
    
            for (Method method : methods) {
                //4.判断方法上是否有check注解
                if (method.isAnnotationPresent(Check.class)) {
                    //5.有的话就执行
                    try {
                        method.invoke(c);
                    } catch (Exception e) {
                        //6.捕获异常  记录到文件中
                        number++;
    
                        bw.write(method.getName() + "方法出异常了 ");
                        bw.newLine();
                        bw.write("异常的名称" + e.getCause().getClass().getSimpleName());
    
                        bw.newLine();
                        bw.write("异常的原因" + e.getCause().getMessage());
    
                        bw.newLine();
                        bw.write("==============");
                        bw.newLine();
                    }
                }
            }
    
            bw.write("本次测试一共出现了"+number+"次异常");
    
            bw.flush();
            bw.close();
        }
    }

    被测试的方法:

    public class Calculator {
        //加法
        @Check
        public void add(){
            System.out.println("1 + 0 = " + (1 + 0));
        }
    
        @Check
        //减法
        public void sub(){
            System.out.println("1 - 0 = " + (1 - 0));
        }
    
        @Check
        //除法
        public void div(){
            System.out.println("1 / 0 = " + (1 / 0));
        }
        public void show(){
            System.out.println("永无bug . . .");
        }
    }
  • 相关阅读:
    配置使用EF常见的一些问题及解决方案
    js定时器的使用(实例讲解)
    MySQL Workbench 修改快捷键
    Linux CentOS 启动 网卡
    Linux CentOS 安装 VMware Tools
    Linux 群晖 DokuWiki 安装
    Linux CentOS 系统安装 和 相关配置
    接口 Postman 提交json对象到后台 Request Payload
    PHP 文件上传
    电商系统 项目管理 GIT的使用
  • 原文地址:https://www.cnblogs.com/caixiaowu/p/12929032.html
Copyright © 2011-2022 走看看