单元测试+反射+注解知识点总结

文章目录

  • 单元测试
      • 测试概述
      • 测试分类
      • Junit使用
  • 反射
      • 反射概述
      • 反射常用的API操作
        • 获取Class对象:有三种方式
      • Method对象、Field对象、Constructor对象
        • 属性对象
        • 构造对象
        • 方法对象
  • 注解
      • 注解概述
      • 注解的作用
      • 常见内置注解(原生)
      • 自定义注解
        • 使用注解(重点)
      • 元注解

单元测试

测试概述

在我们编写代码的时候,开发了很多功能,我们需要对这些已经开发好的功能提前进行测试,检测功能方法是否有漏洞,是否有bug,这个时候我们可以使用Junit单元测试对我们开发的代码进行测试。

Junit是Java语言的单元测试框架,属于第三方的一个工具,一般情况下我们需要导入相应的jar包,对于目前使用的集成开发工具自带的,我们今天是以Idear开发工具为主

Junit属于白盒测试

测试分类

  • 黑盒测试:大多数测试的细节隐藏起来,通常使用的一些软件进行测试
  • 白盒测试:大多数是需要写一些代码进行测试,我们能够看到一些测试的流程.

Junit使用

  • 步骤
    1. 下载一个Junit对应的版本jar包
    2. 添加jar依赖到工程里面
    3. 定义一个测试类
      • 建议:
        • 测试类名:被测试的类Test 如:UserTest、PeopleTest、CalculatorTest…
        • 测试类:应该放到测试资源包中
        • 测试包:xxx.xxx.test 如:com.zhiyou100.test.user
      • 定义测试方法:可以实现独立运行 Junit4/Junit5
        • 建议:
          • 方法名:test被测试的功能方法名 如:testGetName()、testAddNum()
          • 返回值:void
          • 参数列表:Junit4中–>空参 Junit5—>可以携带
          • 修饰符:一般Junit4中使用public Junit5中使用范围较广
    4. 给方法上添加注解@Test
  • 结果判定
    • 红色—>测试失败,中间可能出现了异常
    • 橘黄色 —> 测试失败 实际的值和我们期望的值不一致
    • 绿色 —>测试成功
    • 一般情况下,我们都是使用**断言(Assert)**操作来处理结果的
      示例代码:
Assert.assertEquals(期望的值,实际的值);
  • Junit的其他测试相关的注解:
    JUnit4中

    • @Test 把一个方法标记为测试方法
    • @Before 每一个测试方法执行前会自动调用一次该方法(搭配@Test一起使用)
    • @After 每一测试方法执行后会自动调用一次该方法(搭配@Test一起使用)
    • @BeforeClass 所有的测试方法执行前执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
    • @AfterClass 所有的测试方法执行后执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
    • @Ignore 暂不执行该测试方法(待定的) (搭配@Test一起使用)

    Junit5中

    • @Test 把一个方法标记为测试方法
    • @BeforeEach 每一个测试方法执行前会自动调用一次该方法(搭配@Test一起使用)
    • @AfterEach 每一测试方法执行后会自动调用一次该方法(搭配@Test一起使用)
    • @BeforeAll 所有的测试方法执行前执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
    • @AfterAll 所有的测试方法执行后执行一次,在测试类还没有进行实例化已经被加载到,标记的方法为静态方法(搭配@Test一起使用)
    • @Disabled 暂不执行该测试方法(待定的) (搭配@Test一起使用)
  • 静态导入

JDK5之后出现的新特性,只要在import后面加上关键字static,就可以把后面类的static修饰的变量和方法导入到本类中。调用的时候和调用本类中的静态成员没有区别。

  • 静态导入格式:import static 包名.类名.静态成员名 ----> import static 包名.类名.*

  • 注意事项:

    • 方法必须是静态的
    • 如果有多个静态方法重名,添加前缀,即添加类名
  • @Test属性操作

    • expected属性 期望测试中携带有异常信息,格式 @Test(expected = NullPointerException.class)如果出现异常,测试成功,如果未出现异常,测试失败

    • timeout属性,用来测试方法的执行时间 格式 @Test(timeout=5),单位为毫秒值,如果运行时间在设置值之内,则测试成功,如果超出了设置值范围,则测试失败。

反射

  • 动态语言

是一类可以在程序运行过程中改变其结构的语言。比如说定义的方法、对象、一些功能代码可以在程序运行中被加载进去,从而达到修改或者删除已有的方法和数据
动态语言:JavaScript(脚本语言)、PHP 、Python、C#等等

  • 静态语言

与动态语言相比,运行时程序结构不发生改变的语言就是静态语言。 如C、C++、Java等
Java虽不是动态语言,但是称之为“准动态语言”,可以利用反射机制来动态的获取类结构信息并且修改类结构信息。Java的动态性使开发更加灵活。

反射概述

  • Reflection,在程序中主要是借助Reflection API获取类结构的内部信息,并且能够直接操作类结构内部信息(属性和方法) 如:Class.forName(“com.mysql.jdbc.Driver”);// 硬编码

  • 类加载进内存后,在堆存当中就产生了一个Class类型对象(一个类在内存当中有且只有一个Class对象),这个对象就包含了完整的类的结构信息(属性、方法、构造方法、类名、静态信息等等).我们可以通过这个对象看到类的内部结构.这个对象就像一面镜子一样.透过这个镜子可以看到类的内部结构.这种形式,我们形象的成为"反射机制".

  • 反射一般把它当成框架的灵魂
    框架:半成品软件,我们可以在框架的基础上进行开发,简化代码

  • 好处:

    • 可以在程序运行过程中 ,动态的操作这些对象
    • 可以达到解耦,提高程序的可扩展性。
  • 借助于Class类、Method类、Filed类、Constructor类实现反射

反射常用的API操作

获取Class对象:有三种方式
  • Class.forName(“类的全路径”):将字节码文件加载进内存当中,返回Class对象
  • 类名.class :通过类名的属性class获取Class对象
  • 对象.getClass():通过getClass()方法获取Class对象,getClass() 是Object类中的方法
  • 总结:不论是通过哪种方式获取到的,同一个字节码文件在一次程序运行过程中,只会生成一个Class对象

Method对象、Field对象、Constructor对象

属性对象
  • 获取属性对象

    • Field getField(String name)
      返回一个 Field对象,它反映此表示的类或接口的指定**公共成员字段 **类对象。
    • Field[] getFields()
      返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
    • Field getDeclaredField(String name)
      返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。 不限制权限修饰符
    • Field[] getDeclaredFields()
      返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。 不限制权限修饰符
  • 设置属性对象值
    void set(Object obj,Object value):第一个参数是对应的实际对象,第二个参数是需要设置的值

  • 获取属性对象值
    Object get(Object obj) : 获取对应的属性值

  • 忽略访问权限修饰符的安全性检查:关闭访问权限
    setAccessiable(boolean flag) 传入true值,关闭访问权限,传入false值,打开访问权限

构造对象
  • 获取构造对象

    • Constructor getConstructor(类… parameterTypes)
      返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共类函数。
    • Constructor[] getConstructors()
      返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
    • Constructor getDeclaredConstructor(类… parameterTypes)
      返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
    • Constructor[] getDeclaredConstructors()
      返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组类
  • 构建对象

    T newInstance(Object … initargs)

  • 如果想使用空参构造,有两种方式:

第一种可以使用Class类中newInstance()  
第二种可以使用Constructor类中的newInstance()

通常使用第一种方式。

方法对象
  • 获取方法对象

    • Method getMethod(String name, 类… parameterTypes)
      返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
    • Array getMethods()
      返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。
  • 执行方法

    • Object invoke(Object obj,Class…parameter)
  • 获取方法的名称

注解

注解概述

我们可以吧注解理解为一种代码级别的说明,功能性说明,是从JDK1.5之后引入的新特性,格式:@注解名称

对比注释,是给开发者看的,对代码没有任何影响,注解,是给JVM看的,具有功能的代码

  • 定义:也叫元数据,是- -种具有代码级别的说明,它同接口、类、枚举是在同一-层次上。它可以声明在类、方法、属性、包局部变量、方法参数等上面,用来对这些元素进行说明,注释。
  • 本质:就是一个接口,该接口默认继承Annotation接口。

注解的作用

在目前的主流应用中主要是替代配置文件(如xml文件)

  • 在Servlet2.5之前不支持注解开发,从Servlet3.0开始支持注解开发,不在需要到web.xml文件中去注册Servlet信息
  • 优点:开发效率高,代码精简度高
  • 缺点:代码耦合性太强,维护困难.

常见内置注解(原生)

  • @Override:是在java.lang包中,告知编译期此方法是重写父类中的方法
  • @SuppressWarning:是在java.lang包中,告知编译期此方法内部有风险,抑制编译时的警告信息.
  • @Deprecated:是在java.lang包中,告知编译期此方法是过时单位,是不被鼓励的,可能有更好的方法替代,但是被此注解标记的方法依旧可以使用

自定义注解

  • 使用关键字**@interface**表示注解

  • 注解中含有抽象方法—>属性,属性的定义格式:修饰符 数据类型 属性名称();

    如果在定义属性时,给属性赋默认值 可以使用default关键字 格式为: 属性名称() default 默认值;

    属性,给注解提供更加详细的信息。

    注解就相当于接口,属性相当于方法

    注意事项

    • 修饰符只能是public abstract 和接口命名要求是一样的 不写会默认添加

    • 数据类型可以有以下:

      • 基本类型
      • String
      • 枚举类型 enum
      • 注解类型
      • Class类型
      • 以上类型的一维数组类型
    • 属性名字为value ,并且注解的属性有且仅有一个属性时,在使用该注解时,可以省略value属性名

      但是如果注解当中有多个属性时,使用时需要显式的添加value属性名。

使用注解(重点)

在类、方法、成员变量、局部变量、方法参数上面添加注解 格式: @注解名称(属性名1=属性值1,属性名2=属性值2,…)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

元注解

  • 概念:元注解的作用就是负责注解其他注解的注解,Java定义了4个标准的meta-annotation类型,他们被用来对其他annotation类型做说明.

  • 这些类型和它们所支持的类在java.lang.annotation包中找到.(@Target,@Retention,@Documented,@Inherited)

    • @Target(ElementType.ANNOTATION_TYPE):用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
      • FIELD: 字段上可以使用
      • METHOD:方法上可以使用
      • PARAMETER:参数上可以使用
      • TYPE:类、接口、枚举、注解上可以使用
      • CONSTRUCTOR:构造方法上面可以使用
      • LOCAL_VARIABLE:局部变量可以使用
      • TYPE_PARAMETER:表示注解可以用于类型参数声明时(1.8引入的)
      • TYPE_USE:类型使用说明(1.8引入的)
    • @Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期
      借助于RetentionPolicy属性,总共有三个取值:
      • SOURCE: 源码级别可见
      • CLASS: 在字节码文件级别可见,包括SOURCE级别
      • RUNTIME:在整个运行阶段可见,包括SOURCE和CLASS,可以通过反射获取
        如果想要解析使用注解,需要把该注解的属性值设定为Runtime值。
        如:RetentionPolicy.RUNTIME
      • (SOURCE
    • @Documented:说明该注解讲被包含在javadoc中,意思生成帮助文档时对应位置上含住该注解信息
    • @Repeatable:元注解@Repeatable是JDK1.8新引入的,它表示在同一个位置重复相同的注解。在没有该注解前,一般是无法在同一个类型上使用相同的注解,它的使用需要借助容器来存储此注解。

    Class 向上限定 意思是说只能传递Annotation以及它的子类
    Class 向下限定 意思是说只能传递Annotation以及它的父类

    • @Inherited:说明子类可以继承父类中的该注解

你可能感兴趣的:(java,单元测试,反射)