十五、Java之单元测试和注解(1)

1 单元测试

1.1 测试分类

黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
白盒测试:需要写代码的。关注程序具体的执行流程。

在这里插入图片描述

1.2 Junit介绍

Junit是一个Java语言的单元测试框架,属于白盒测试,简单理解为可以用于取代java的main方法。Junit属于第三方工具,需要导入jar包后使用。

  1. 编写测试类,简单理解Junit可以用于取代java的main方法。
  2. 在测试类方法上添加注解 @Test。
  3. @Test修饰的方法要求:public void 方法名() {…} ,方法名自定义建议test开头,没有参数。(可以把这个方法看做main方法
  4. 添加Junit库到lib文件夹中,然后进行jar包关联。

1.3 注意事项

注意:
     1 该方法的返回值类型,必须写为void
     2 该方法必须没有参数列表
     	  如果需要有参数列表,可以在测试方法外添加普通带参数的方法
     3 该方法不能是静态方法

1.4 配合常用注解

- @Test,用于修饰需要执行的测试方法。
- @Before,修饰的方法会在测试方法之前被自动执行。
- @After,修饰的方法会在测试方法执行之后自动被执行。

2 注解

2.1 注解概述

JDK1.5新特性 注解 Annotation,与类、接口、枚举是在同一个级别。

 * 作用:
 *   说明:对代码进行说明生成doc文件(API)
 *   检查:检测代码,是否有错误  如:@Override 方法重写
 *   分析:对代码的分析,起到替代配置文件

常见注解有:
 *     @Override  方法为重写
 *       JDK 1.5版本,支持父类方法重写
 *       JDK 1.6版本,支持父类,支持接口
 *
 *     @Deprecated 方法已经过时,不推荐使用
 *       调用的时候,开发工具,加删除线
 *
 *     @SuppressWarnings  抑制警告

2.2 自定义注解

 * 自定义注解:
 *   定义类,关键字 class
 *   定义接口,关键字 interface
 *   定义注解,关键字 @interface  annotation
 *
 *  JDK5新增关键字  @interface
 *  版本兼容性, 产生新的关键字,以前程序不稳定
 *
 *  注解编译后为class文件
 *
 *  注解成员定义:
 *    注解中成员,称为注解的属性
 *    固定格式:
 *      数据类型  属性名() [default 默认值];
 *
 *    数据类型要求:
 *       属性的数据类型,可以是基本类型(8个),String
 *       枚举类型(enum), Class类型,其他注解类型
 *       以上的数据类型是允许的,包含了以上类型的一维数组

举个栗子:

public @interface Student {
  String name(); // 姓名
  int age() default 18; // 年龄
  String gender() default "男"; // 性别
} 
// 该注解就有了三个属性:name,age,gender

2.3 使用自定义注解

/**
 * 使用注解,就是为注解的属性赋值
 * 格式:
 *   @注解名(属性名=值,属性名=)
 *   如果注解的属性有默认值,可以不赋值
 *
 *   String[] author();作者是字符串的数组
 *   数组的赋值{}
 *
 *   如果注解中的属性只有一个,名字是value
 *   赋值的时候,可以省略value不写
 *   属性是数组,数组中只有一个元素,大括号可以不写
 *   如:// 使用注解Book
		public class BookShelf {
		    @Book("西游记")
		    public void showBook(){}
		}
 */
//@Teacher("张三")
public class BookShelf {
    @Book(bookName = "红楼梦",price = 200.99, author = {"曹雪芹","高额"})
    public void sellBook(){

    }
}

2.4 注解之元注解

 * JDK的元注解,比喻注解的总管
 * 管理其他的注解
 *
 * 元注解对我们的注解进行控制
 * 1: 控制我们的注解,可以写在哪里,(类,方法,变量上,包...)
 * 2: 控制我们的注解的生命周期
 *
 * JDK的2个元注解
 *
 * @Target  指示其他注解,出现的位置
 *    ElementType[] value(); 数组,可以赋值多个
 *    ElementType是数据类型,是枚举
 *    枚举的属性,都是静态修饰,直接类名调用
 *      TYPE, 其他注解可以写在类上
 *      FIELD,其他注解可以写在成员变量
 *      METHOD,其他注解可以写在方法上
 *      PARAMETER,其他注解可以写在方法参数上
 *      CONSTRUCTOR,其他注解可以写在构造方法上
 *
 *  @Retention 指示其他注解的生命周期
 *     RetentionPolicy value(); 不是数组,赋值一个
 *     RetentionPolicy数据类型
 *     枚举的属性,都是静态修饰,直接类名调用
 * 	   SOURCE 注解仅存在于源码中java文件中
 *     CLASS  注解存在于编译后的class文件中(不会加载进内存)
 *     RUNTIME 运行时期的内存中

举栗子:

@Target(ElementType.METHOD)  //@Override注解只能写在方法上
@Retention(RetentionPolicy.SOURCE) //@Override注解仅存在于源码中,编译class中不会有,更不会被加载进内存
public @interface Override {
}

2.5 注解解析

案例需求:

获取BookShelf类上,注解Book的属性值
 *    @Book(bookName = "红楼梦",price = 200.99, author = {"曹雪芹","高额"})

 *      注解的解析思想:
 *      1: 反射带有注解的类
 *      2: 反射方法
 *      3: 判断方法上是否有注解
 *      4: 获取这个注解
 *      5: 获取注解的属性值
 *    接口 AnnotatedElement 方法:
 * 		实现接口的具体实现类:AccessibleObject, Class, Constructor, Field, Method, Package ,它们的对象可以调用一下方法
 * 		结论: 注解解析,与反射密切相关
 * 		 
 * 		1 判断方法上是否有注解:
 *       	boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
 *       解释:
 *       	返回值
 * 				是布尔值: 返回的true,该对象上有注解,返回的是false,该对象没有注解
 *			传参:
 *          	Class<? extends Annotation> annotationClass
 *          	传递class文件对象  ?不知道, 肯定?继承Annotation
 *          	Annotation接口,是所有注解的顶级接口,可以传递任意的注解!!
 *
 *
 *      2  返回注解类型的对象
 *       <T extends Annotation> getAnnotation(Class<T> annotationClass)
 *       解释:
 *         传参:
 * 				是任意注解的class文件对象
 *		   返回值:
 *         		传递什么类型,返回什么类型
 *

案例具体实现:

public class AnnotationJieXi {
    @Test
    public void test()throws Exception{
        //反射BookShelf
        Class c = Class.forName("com.itheima.our.BookShelf");
        //反射获取方法sellBook
        Method method = c.getMethod("sellBook");
        System.out.println(method);
        //方法判断是否有注解
        //参数,传递注解的class文件对象
        boolean b = method.isAnnotationPresent(Book.class);
        //method对象调用方法,获取直接
        Book book = method.getAnnotation(Book.class);
        //获取出Book注解的属性
        String bookName = book.bookName();
        double price = book.price();
        String[] strings = book.author();
        System.out.println(bookName+price+ Arrays.toString(strings));

    }
}

2.6 lombok注解

 * lombok 第三方jar包中 一些注解使用
 *
 * @Getter
 * @Setter
 * 生成 get/set方法
 * 使用,写在类上,所有的成员变量,都生效
 * 如果写在成员变量上,只有这个变量可以使用
 *
 * @AllArgsConstructor 生成满参数构造方法
 *
 * @NoArgsConstructor 生成无参数构造方法
 *
 * @ToString 生成toString()
 *
 * @EqualsAndHashCode 生成hashCode()和equals()方法
 *
 * @Data注解 = @Getter  @Setter @NoArgsConstructor  @ToString @EqualsAndHashCode
 *
 *
 *  编译原理,安装插件
 *  使用注解,插件帮助写出这些方法
@Data
public class Person {
    private String name;
    private int age;
    private String address;

}

IDEA中配置此插件,见装机必备专栏

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页