Junit、反射、注解

Junit单元测试

  • 测试分类

    • 黑盒测试:看不到里面,只能通过输入输出判断错误,一般都是穷举
    • 白盒测试:看得到里面,通过逻辑结构来判断错误,耗费较高,一般进行的是单元测试
  • Junit使用:白盒测试

    • 步骤
      1. 定义一个测试类
        • 被测试的类名最好写成Test CalculatorTest
        • 包名:xxx.xxx.xx.test cn.it.test
      2. 定义测试方法:可以独立运行
        • 方法名:test+方法名 testAdd()
        • 返回值:void
        • 参数列表:列表
      3. 给方法加@Test
      4. 导入junit的依赖
      5. 一般输出并不能知道结果是否正确,只会报错,所以这时使用断言Assert.assertEquals(预期结果,得到结果);
package junit;

public class Calculator {

    public int add (int a, int b){
        return a + b;
    }

    public int sub(int a, int b){
        return a - b;
    }
}
package junit;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class CalculatorTest {

    @Before
    public void init(){
        System.out.println("init......");
    }
    
    @After//即使中间的方法出现异常,也会被执行,所以一般用于资源的释放
    public void close(){
        System.out.println("close......");
    }

    //需要引入junit(ALT+ENTER)
    @Test
    public void testAdd(){
        Calculator c = new Calculator();
        System.out.println(c.add(1,2));

        //断言
        Assert.assertEquals(1,c.add(1,2));
    }
}

反射

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

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

在这里插入图片描述

Java代码在计算机中先进行Javac编译成class文件(source阶段),通过类加载器变成类对象(class类对象阶段),然后被创建对象使用(Runtime运行阶段)

  • 获取class对象(获取字节码对象,对应三个阶段)

    • Class.forname(“全类名”);

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

      • 多用于参数的传递
    • 对象.getclass()

      • 多用于对象的获取字节码的方式
  • 同一个字节码文件(*.class)在一次程序的运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个。

  • Class对象功能

    • 获取功能
      • 获取成员变量们
      • 获取构造方法们
      • 获取成员变量们
      • 获取类名
  • 案例

pro.properties

className = it.Person
methodName = eat

Test.java

package it;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class Test {

    public static void main(String[] args) throws Exception {

        //1加载配置文件
        //1.1创建Properties对象
        Properties properties = new Properties();
        //1.2加载配置文件,转换为一个集合
        //1.2.1获取class目录下的配置文件
        ClassLoader classLoader = Test.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        properties.load(is);

        //2.获取配置文件定义的资源
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        //3.加载该类进内存,
        Class cls = Class.forName(className);
        //4.创建对象
        Object o = cls.newInstance();
        //5.获取方法
        Method method = cls.getMethod(methodName);
        //6.执行方法
        method.invoke(o);
    }
}

Person.java

package it;

public class Person {

    private String a;
    protected String b;
    public String c;
    String d;

    public Person() {
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    public String getD() {
        return d;
    }

    public void setD(String d) {
        this.d = d;
    }

    public void eat(){
        System.out.println("eat,,,");
    }
    @Override
    public String toString() {
        return "Person{" +
                "a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }
}

注解

  • 注解:说明程序的,给计算机看的。

  • 定义:注解,可以看作是对 一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值

    注解也就是Annotation,相信不少人也和我之前一样以为和注释和doc一样,是一段辅助性的文字,其实注解不是这样的。

    从JDK5开始,java增加了对元数据(描述数据属性的信息)的支持。其实说白就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。

  • 作用分类:

    1. 编写文档:通过代码标识里的元数据生成文档【生成doc文档】
    2. 代码分析:通过代码标识里的元数据对代码进行分析【使用反射】
    3. 编译检查:通过代码标识里的元数据让编译器能够实现基本的编译检查【override】
  • 自定义注解

    元注解
    public @interface 注解名{
    }
    
  • 本质:

    public interface 注解名 extends java.lang.annotation.Annotation {
    }
    
  • 属性:接口中的抽象方法

    • 要求:
      1. 属性的返回值类型只有下列取值
        • 基本数据类型
        • String
        • 枚举
        • 注解
        • 以上类型数组
      2. 定义了属性,在使用时需要给属性赋值
        • 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
        • 如果只有一个属性需要赋值,并且属性名称为value,则value可以省略,直接定义值即可
        • 数组赋值时。使用{}包裹
  • 元注解:用于描述注解的注解

    • @Target:描述注解能够作用的位置
    • @Retention:描述注解能够被保留的阶段
    • @Documented:描述注解是否能被抽取到api文档
    • @Inherited:描述注解是否能被继承
  • 案例:

check注解

package it;

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)
public @interface Check {
}

Calculator

package it;

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 mul(){
        System.out.println("1 * 0 = " + (1 * 0));
    }

    @Check
    public void div(){
        System.out.println("1 / 0 = " + (1 / 0));
    }

}

TestCheck

package it;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;

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 num = 0;
        BufferedWriter bw = new BufferedWriter(new FileWriter("BUG.txt"));

        for (Method method : methods) {
            //判断方法是是否有Check注解
            if (method.isAnnotationPresent(Check.class)){//有Check注解就执行
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    num ++;

                    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("本次测试一共有" + num +"次异常");

        bw.flush();
        bw.close();
    }
}





*注:所有文章都只为自己做笔记*
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值