25.单元测试、反射

news2024/10/5 13:22:11

一.单元测试

1.1 什么是单元测试

单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法。因此,单元测试就是针对Java方法进行的测试,进而检查 方法的正确性。

1.2 目前测试方法是怎么进行的

①只有一个main方法,如果一个方法的测试失败了,其他测试方法会受到影响。
②无法得到测试的结果报告,需要程序员自己去观察测试是否成功。
③无法实现自动化测试。

1.3 Junit

1.Junit概述

JUnit是使用Java语言实现的单元测试框架,它是开源的,Java开发者都应当学习并使用JUnit编写单元测试。

此外,几乎所有的IDE工具都集成了JUnit,这样我们就可以直接在IDE中编写并运行JUnit测试,JUnit目前最新版本是5

2.Junit优点
  • JUnit可以灵活的选择执行哪些测试方法,可以一键执行全部测试方法。
  • Junit可以生成全部方法的测试报告。
  • 单元测试中的某个方法测试失败了,不会影响其他测试方法的测试。

1.4 单元测试快速入门

步骤

  1. 将Junit的jar包导入到项目中。
  2. 编写测试方法:该测试方法必须是公共的无参数无返回值的非静态方法。
  3. 在测试方法上使用@Test注解:标注该方法是一个测试方法
  4. 在测试方法中完成被测试方法的预期正确性测试。
  5. 选中测试方法,选择“JUnit运行” ,如果测试良好则是绿色;如果测试失败,则是红色

1.5 Junit常用注解

Junit常用注解(Junit 4.xxxx版本):

Junit常用注解(Junit 5.xxxx版本):

1.6 代码实例

二.反射(重要)

2.1 反射概述

        反射是指对于任何Class类,在运行的时候,可以获取类的字节码文件对象,然后可以解析类中的全部成分。

  • 在运行时,可以直接得到这个类的构造器对象:Construtor。
  • 在运行时,可以直接得到这个类的成员变量对象:Field。
  • 在运行时,可以直接得到这个类的成员方法对象:Method。

这种运行时动态获取类信息以及动态调用类中成分的能力称为反射。

2.2 反射的关键

反射的第一步都是先得到编译后的Class文件对象,然后就可以得到Class的全部成分。

2.3 反射获取类对象

反射的第一步就是获取Class类的对象,共有三种方式。

  • 方式一:使用Class类中的静态方法forName,装入类,并做类的静态初始化,返回Class的对象代码格式如下:Class c1 = Class.forName("全类名");//全类名就是src下的全包名
  • 方式二:JVM将使用类装载器,将类装入内存 (前提是:类还没有装入内存),不做类的初始化工作,返回Class的对象,代码格式如下: Class c2 = 类名.Class
  • 方式三:使用Object类中的getClass方法获取,会对类进行静态初始化,代码格式如下:    Class c3 = 对象.getClass()

2.4 反射获取构造器对象

步骤:

  1. 首先得到类对象
  2. 通过类对象获取构造器对象
  3. 使用构造器对象创建类的对象

Class类中用于获取构造器的方法:

Constructor类中用于创建对象的方法:

作用

获取构造器的作用依然是获取一个对象并返回。

注意事项

如果某个构造器是私有的,那么需要打开权限(暴力反射),然后再创建对象。

范例

public class TestDemo {
    //目标:掌握如何获取构造器对象,并利用构造器对象创建对象

    //获取所有公共的构造器对象
    @Test
    public void getConstructors(){
        //1.获得类对象
        Class class1 = Student.class;
        //2.获得所有公共构造器对象
        Constructor[] constructors = class1.getConstructors();
        //3.遍历构造器数组
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName()+"===>"+constructor.getParameterCount());
        }
    }

    //获取所有的构造器对象,无论构造器是公开的,还是私有的
    @Test
    public void getDeclaredConstructors(){
        //1.获取类对象
        Class class2 = Student.class;
        //2.获取所有构造器对象
        Constructor[] allConstructor = class2.getDeclaredConstructors();
        //3.遍历构造器对象
        for (Constructor constructor : allConstructor) {
            System.out.println(constructor.getName()+"===>"+constructor.getParameterCount());
        }
    }

    //获取单个构造器对象
    @Test
    public void getConstructor() throws Exception{
        //1.获取类对象
        Class class3 = Student.class;
        //2.获取单个构造器
        Constructor constructor = class3.getDeclaredConstructor(String.class,int.class);
        constructor.setAccessible(true);
        //3.通过这个构造器创建对象
        Student s = (Student) constructor.newInstance("张三",12);
        System.out.println(s);

    }

    //获取单个构造器对象,无视构造器的访问权限
    @Test
    public void getDeclaredConstructor() throws Exception{
        //1.获取类对象
        Class class3 = Student.class;
        //2.获取单个构造器
        Constructor constructor = class3.getDeclaredConstructor();
        //3.暴力反射
        constructor.setAccessible(true);
        //4.通过这个构造器创建对象
        Student student = (Student) constructor.newInstance();
        System.out.println(student);
    }
}

2.5 反射获取成员变量对象

步骤:

  1. 首先得到类对象
  2. 从类对象中获取成员变量对象

Class类中用于获取成员变量的方法:

Field中用于取值、赋值的方法

作用

依然是为某个对象中对应的成员变量取值和赋值。

注意事项

如果某个成员变量是私有的,那么需要打开权限(暴力反射),然后再取值、赋值。

代码示例

public class FieldDemo1 {
    //目标:掌握成员变量对象的获取,并对某个对象中相应的成员变量进行取值和赋值

    //通过反射获取所有成员变量对象
    @Test
    public void getFields() throws Exception {
        //1.获取类对象
        Class class1 = Student.class;
        //2.获取所有成员变量对象
        Field[] fields = class1.getDeclaredFields();
        //3.遍历所有成员变量对象
        for (Field field : fields) {
            System.out.println(field.getName()+"===>"+field.getType());
        }

    }

    //通过反射获取一个成员变量并赋值
    @Test
    public void getField() throws Exception {
        //1.获取类对象
        Class class1 = Student.class;
        //2.获取成员变量对象
        Field name = class1.getDeclaredField("name");
        //3.暴力反射
        name.setAccessible(true);
        //4.对成员变量赋值
        Student s = new Student();
        name.set(s,"张三");
        //5.打印对象
        System.out.println(s);
    }

    //通过反射获取一个成员变量并取值
    @Test
    public void getField2() throws Exception {
        //1.获取类对象
        Class class1 = Student.class;
        //2.获取成员变量对象
        Field name = class1.getDeclaredField("name");
        //3.暴力反射
        name.setAccessible(true);
        //4.对成员变量取值
        Student s = new Student("李四",12);
        String s1 = (String) name.get(s);
        //5.打印成员变量
        System.out.println(s1);
    }
}

2.6 反射获取成员方法对象

步骤:

  1. 首先获取类对象
  2. 通过类对象获取Method对象
  3. 运行方法

Class类中用于获取成员方法的方法:

Method类中用于触发执行的方法:

作用

获取成员方法的作用依然是在某个对象中执行此方法

注意事项

如果某个成员方法是私有的,那么需要打开权限(暴力反射),然后再执行此方法。

2.6 反射的作用——绕过编译阶段为集合添加数据

反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时可以为集合存入其他任意类型的元素。

1.原因

泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList了,泛型相当于被擦除了。

2.代码示例

2.7 反射的作用——通用框架的底层原理

1.需求: 给你任意一个对象,在不清楚对象字段的情况可以把对象的字段名称和对应值存储到文件中去。

2.代码示例

//框架代码:
public class MyBatisUtils {
    public static void save(Object o){
        try (
                PrintStream ps = new PrintStream(new FileOutputStream("junit-reflect-annotation-proxy/src/reflect.txt",true))
                ){
            //1.得到类对象
            Class aClass = o.getClass();
            ps.println("================="+aClass.getSimpleName()+"=================");
            //2.得到类中全部的成员变量对象
            Field[] fields = aClass.getDeclaredFields();
            //3.得到全部成员变量对象的名字和值

            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                String  value = field.get(o)+" ";
                //4.保存到文件中
                ps.println(name+"---"+value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//测试代码:
public class ReflectDemo1 {
    public static void main(String[] args) {
        //目标:利用反射技术,做一个通用框架
        //向对象中添加数据,并将对象传到框架中
        Student s = new Student("张三",17,'男',12,"3000");
        MyBatisUtils.save(s);

        Tercher t = new Tercher("张三",17,'男',"王标");
        MyBatisUtils.save(t);

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/662145.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可观测性最佳实践 | 警惕!未知的风险正在摧毁你的系统

无声的刺客最为致命,往往表面看似云淡风轻,实际早已危机重重,血雨腥风一触即发。这样的场面看似离我们很遥远,但每个开发运维人员实际都遇到过。 在全球数字经济大潮下,现代企业纷纷投身于业务数字化转型的浪潮。越来越…

java8 (jdk 1.8) 新特性—— 方法引用+构造器引用

1. 方法引用 方法引用 其实 本质上 就是Lambda 表达式 ,之前已经知道 Lambda 是作为一个函数式接口的实例 ,因此,方法引用也就是一个函数式接口的实例 使用的情况: 当要将值传给Lambda 体,已经有实现的方法&#xff…

【Python 随练】判断101到200的素数

题目: 判断 101-200 之间有多少个素数,并输出所有素数。 简介: 在本篇博客中,我们将解决一个常见的问题:判断101到200之间的素数,并输出所有素数的列表。我们将给出问题的解析,并提供一个完整…

2023年了要怎么理解原型和原型链

1.prototype和__proto__有什么不可告人的关系? 说道原型对象,那一定绕不开几个概念: prototype,__proto__,constructor。 首先解释一下prototype是什么,原型对象。V8引擎给所有函数内置的一个对象。也就是只要创建的…

瑞丽-伯纳德对流的拉格朗日拟序结构(FTLE场结果对比)

FTLE场,即有限李雅普诺夫指数场是识别拉格朗日拟序结构的一种方法,其主要思路是如下: 1、t时刻在场内均匀布置粒子 2、计算t–>tT时刻后粒子的位置,这里粒子任意时刻的速度有速度场插值得到 3、根据两个时刻的粒子位置计算得…

资讯 |智汇云舟受邀出席WGDC大会并获“年度最具创新力企业“奖项

5月17日,由泰伯网主办的第十二届WGDC2023全球地理信息开发者大会在北京隆重召开。开幕式上重磅发布了“2023年度最具创新力”榜单,智汇云舟凭借技术创新研发与应用方面取得的诸多突破,获数字孪生赛道“年度最具创新力企业"奖项。公司产品…

Django高级扩展之Paginator分页实现

在项目中很常见的一种功能,主要用于大量数据在一页显示过于冗长,分为一页显示多条数据,分隔为多页显示;并常与条件筛选结合使用。 目录 Paginator对象 创建对象 属性 方法 异常 Page对象 创建对象 属性 方法 Paginator与…

华为OD机试之阿里巴巴找黄金宝箱(I)

阿里巴巴找黄金宝箱(I) 题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字,箱子中可能有一个黄金宝箱。 黄金宝箱满足排在它之前的所有箱子数字…

Kubernetes Pod 生命周期

Pod 生命周期是其从创建开始至终止退出的事件范围。 Pod 状态 Pending API server 创建了 Pod 对象并已存入 etcd 中,但尚未调度完成或仍处于从镜像仓库下载镜像的过程中。Running Pod 已经被调度至某节点,并且所有容器都已经被 kubelet 创建完成。Suc…

spss分析方法-聚类分析

聚类分析是根据研究对象的特征,按照一定标准对研究对象进行分类的一种分析方法。下面我们主要从下面四个方面来解说: 实际应用理论思想建立模型 分析结果 一、实际应用 聚类分析的目标就是在相似的基础上收集数据来分类。 聚类源于很多领域&#xf…

安装虚幻引擎

1、下载和安装 Epic Games启动程序。 下载地址:https://www.unrealengine.com/zh-CN/download 进入网站你可以看到下载信息和推荐系统要求等: 点击“下载启动程序”即可下载,或者直接点击下载链接:https://epicgames-download1.ak…

37岁985硕士,投上千份简历无人问津......该何去何从

前言 简单自我介绍一下,我老刘,37岁失业的985硕士 ,13年其实可以直接入编的我,其实都不需要考试了,可以直接入职,但是我并没有选择去,后面直接选择了新闻周刊干了四年,后面换了一家…

【福利】不用考试可以增持CSPM-2证书?有PMP证书才行!

2021年10月,中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系,开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会(CAS)组织开展的项…

CSS查缺补漏之《过渡效果与动画效果》

过渡 过渡效果使用transition属性表示&#xff0c;设置在需要过渡效果的元素上&#xff0c;它可以在让元素从一种样式平滑过渡为另一种样式。下面会依次介绍其属性值~ 示例代码如下&#xff1a; <div class"box">世界你好 </div> .box {width: 200px…

多态下,为什么使用virtual修饰析构函数

多态下,为什么使用virtual修饰析构函数 问题&#xff1a; 用virtual修饰的析构函数和非虚函数的析构函数有什么区别&#xff1f; 当时以为&#xff1a;只有经过virtual修饰的析构函数&#xff0c;派生类生命周期结束时&#xff0c;才会自动的先调用派生类的析构函数&#xff0…

mybatisplus连接sqlserver配置

目录 前言&#xff1a; 一&#xff1a;所需依赖&#xff1a; 二&#xff1a;application.yml 三:分页插件 前言&#xff1a; 本文主要讲解连接sqlserver的配置 一&#xff1a;所需依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> &l…

hutool工具包的实用方法简单介绍

说明&#xff1a;Hutool是一个小而全的Java工具类库&#xff08;详细参考&#xff1a;https://hutool.cn/docs/#/&#xff09;&#xff0c;使用前需要先添加依赖 &#xff08;添加依赖&#xff09; <dependency><groupId>cn.hutool</groupId><artifactId…

Redis从入门到精通进阶篇之持久化RDB

文章目录 RDB持久化工作原理 Redis 6的持久化机制主要有两种&#xff1a;RDB&#xff08;Redis DataBase&#xff09;和AOF&#xff08;Append Only File&#xff09;。本文将详细介绍这两种持久化方式的工作原理和配置要点。 RDB持久化 RDB持久化是将当前进程的数据生成快照…

项目经理,35岁以后就很难再有竞争力了吗?

早上好&#xff0c;我是老原。 知乎热榜上有一个问题吸引了我的注意&#xff1a; 说句公道话&#xff0c;35岁确实是个坎&#xff0c;这个坎在吃青春饭的行业来说&#xff0c;格外明显。 体力和精力都大不如年轻人&#xff0c;从性价比的角度来说&#xff0c;公司还是不会用…

2.2ORBSLAM3之几种特征点提取方法

0.简介 本节对ORB特征、SIFT特征、SURF特征、Harris角点、Shi-Tomas角点的提取与描述子计算原理进行总结&#xff0c;其中Harris角点、Shi-Tomas角点是关键点&#xff0c;没有对应的描述子&#xff0c;一般用于光流跟踪(Vins系列算法)。 综合所有的特征检测算法来看&#xff…