Day20-【Java SE高级】单元测试 反射 注解 动态代理

一、单元测试

就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试。

1. 咱们之前是如何进行单元测试的?有啥问题?

  • 只能在main方法编写测试代码,去调用其他方法进行测试。
  • 无法实现自动化测试,一个方法测试失败,可能影响其他方法的测试。
  • 无法得到测试的报告,需要程序员自己去观察测试是否成功。

2. Junit单元测试框架

  • 可以用来对方法进行测试,它是第三方公司开源出来的(很多开发工具已经集成了Junit框架,比如IDEA)
2.1 优点
  • 可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立.
  • 不需要程序员去分析测试的结果,会自动生成测试报告出来。
2.2 快速入门

需求:某个系统,有多个业务方法,请使用Junit单元测试框架,编写测试代码,完成对这些方法的正确性测试。
具体步骤

  • 将Junit框架的jar包导入到项目中(注意:IDEA集成了Junit框架,不需要我们自己手工导入了)
  • 为需要测试的业务类,定义对应的测试类,并为每个业务方法,编写对应的测试方法(必须:公共、无参、无返回值)
  • 测试方法上必须声明@Test注解,然后在测试方法中,编写代码调用被测试的业务方法进行测试;
  • 开始测试:选中测试方法,右键选择“JUnit运行”,如果测试通过则是绿色;如果测试失败,则是红色

可以右键模块,run all test自动化一键测试,可以点击测试类的运行运行该类的所有自动化测试。

package com.jingwei;

import org.junit.Assert;
import org.junit.Test;

public class StringUtilTest {
    @Test
    public void testPrintNumber(){
        StringUtil.printNumber("admin");
        StringUtil.printNumber(null);
    }
    @Test
    public void testGetMaxIndex(){
        int maxIndex = StringUtil.getMaxIndex(null);
        System.out.println(maxIndex);

        int maxIndex1 = StringUtil.getMaxIndex("admin");
        System.out.println(maxIndex1);

        //断言机制:程序员可以通过预测业务方法的结果
        Assert.assertEquals(4,maxIndex1);
    }
}

package com.jingwei;

public class StringUtil {
    public static void printNumber(String name) {
        if(name==null){
            System.out.println("名字长度是:" +0);
            return;
        }
        System.out.println("名字长度是:" + name.length());
    }

    //求字符串的最大索引
    public static int getMaxIndex(String data) {
        if (data == null) {
            return -1;
        }
        return data.length()-1;
    }
}

2.3 常用注解

在这里插入图片描述

package com.jingwei;

import org.junit.*;

import java.net.Socket;

public class StringUtilTest {
    private Socket socket;
    private static Socket  socket1;
    @Before
    public void setUp() throws Exception {
        System.out.println("--->Setup Before 测试配置文件执行了---------");
        socket = new Socket("127.0.0.1", 8888);
    }
    @After
    public void setUp1() throws Exception {
        System.out.println("--->Setup After 测试配置文件执行了---------");
        socket.close();
    }
    @BeforeClass
    public static void setUp2() throws Exception {
        System.out.println("--->Setup BeforeClass 测试配置文件执行了---------");
        socket1=new Socket("127.0.0.1", 8888);
    }
    @AfterClass
    public static void setUp3() throws Exception {
        System.out.println("--->Setup AfterClass 测试配置文件执行了---------");
        socket1.close();
    }

    @Test
    public void testPrintNumber(){
        StringUtil.printNumber("admin");
        StringUtil.printNumber(null);
    }

    @Test
    public void testGetMaxIndex(){
        int maxIndex = StringUtil.getMaxIndex(null);
        System.out.println(maxIndex);

        int maxIndex1 = StringUtil.getMaxIndex("admin");
        System.out.println(maxIndex1);

        //断言机制:程序员可以通过预测业务方法的结果
        Assert.assertEquals(4,maxIndex1);
    }
}

在这里插入图片描述

二、反射

在这里插入图片描述

2.1 反射(Reflection)

反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。
在这里插入图片描述

2.2 反射学什么?

学习获取类的信息、操作它们
1、反射第一步:加载类,获取类的字节码:Class对象
2、获取类的构造器:Constructor对象
3、获取类的成员变量:Field对象
4、获取类的成员方法:Method对象
全部认识完后,再看反射的应用场景

在这里插入图片描述

package com.reflect;

public class ReflectTest1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class studentClass = Student.class;
        System.out.println(studentClass.getName());
        System.out.println(studentClass.getSimpleName());

        Class aClass = Class.forName("com.reflect.Student");
        System.out.println(aClass.getName());

        System.out.println(studentClass == aClass);

        Class tom = new Student("Tom",11).getClass();
        System.out.println(tom.getName());
        System.out.println(tom==studentClass);
    }
}

class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

2.3 获取类的构造器

在这里插入图片描述

package com.reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class ReflectTest2 {
    @Test
    public void testGetConstructors() {
        //1. 反射第一步:必须先得到这个类的class对象
        Class<Student> studentClass = Student.class;
        //2. 获取类的全部构造器
//        Constructor[] constructors = studentClass.getConstructors();
        Constructor[] constructors = studentClass.getDeclaredConstructors();
        //3. 遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "--->"
                    + constructor.getParameterCount());
        }

    }

    @Test
    public void testGetConstructor() throws NoSuchMethodException {
        Class<Student> studentClass = Student.class;
//        Constructor<Student> constructor = studentClass.getConstructor();
        Constructor constructor = studentClass.getDeclaredConstructor();
        System.out.println(constructor.getName() + "--->"
                + constructor.getParameterCount());

        Constructor constructor1 = studentClass.getDeclaredConstructor(String.class,int.class);
        System.out.println(constructor1.getName() + "--->"
                + constructor1.getParameterCount());
    }
}

获取类构造器的作用:依然是初始化一个对象返回
在这里插入图片描述

package com.reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectTest2 {
    @Test
    public void testGetConstructors() {
        //1. 反射第一步:必须先得到这个类的class对象
        Class<Student> studentClass = Student.class;
        //2. 获取类的全部构造器
//        Constructor[] constructors = studentClass.getConstructors();
        Constructor[] constructors = studentClass.getDeclaredConstructors();
        //3. 遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "--->"
                    + constructor.getParameterCount());
        }

    }

    @Test
    public void testGetConstructor() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> studentClass = Student.class;
//        Constructor<Student> constructor = studentClass.getConstructor();
        Constructor constructor = studentClass.getDeclaredConstructor();
        System.out.println(constructor.getName() + "--->"
                + constructor.getParameterCount());
        constructor.setAccessible(true);//禁止检查访问权限,可以访问私有构造器,破坏封装性能
        Student o = (Student) constructor.newInstance();
        System.out.println(o);


        Constructor constructor1 = studentClass.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor1.getName() + "--->"
                + constructor1.getParameterCount());
        Student o1 = (Student) constructor1.newInstance("叮当猫", 3);
        System.out.println(o1);
    }
}

2.3 获取类的成员变量

在这里插入图片描述

在这里插入图片描述

    @Test
    public void testGetField() throws NoSuchFieldException, IllegalAccessException {
        //1. 反射第一步:必须是先得到类的Class对象
        Class<Student> studentClass = Student.class;
        //2. 获取类的全部成员变量。
        Field[] fields = studentClass.getDeclaredFields();
        //3. 遍历这个成员变量数组
        for (Field field : fields) {
            System.out.println(field.getName() + "--->"+field.getType());
        }
        //4. 定位某个成员变量
        Field declaredField = studentClass.getDeclaredField("name");
        System.out.println(declaredField.getName()+"--->"+declaredField.getType());

        Field age = studentClass.getDeclaredField("age");
        System.out.println(age.getName()+"--->"+age.getType());

        //赋值
        Student student = new Student();
        declaredField.setAccessible(true);
        declaredField.set(student,"加菲猫");
        System.out.println(student);

        //取值
        String rs = (String) declaredField.get(student);
        System.out.println(rs);
    }

2.4 获取类的成员方法

在这里插入图片描述
在这里插入图片描述

    @Test
    public void testGetMethod() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<Student> studentClass = Student.class;
        Method[] methods = studentClass.getDeclaredMethods();
        System.out.println("所有成员方法如下:");
        for (Method method : methods) {
            System.out.println(method.getName() + "--->"+method.getParameterCount()
            +"--->"+method.getReturnType());
        }
        System.out.println("---------");
        Method declaredMethod = studentClass.getDeclaredMethod("setName", String.class);
        System.out.println(declaredMethod.getName()+"--->"+declaredMethod.getParameterCount()
        +"--->"+declaredMethod.getReturnType());

        System.out.println("---------");
        Method declaredMethod1 = studentClass.getDeclaredMethod("getName");
        System.out.println(declaredMethod.getName()+"--->"+declaredMethod.getParameterCount()
                +"--->"+declaredMethod.getReturnType());

        Student student = new Student("Tom", 12);
        String invoke = (String) declaredMethod1.invoke(student);
        System.out.println(invoke);

        Object invoke1 = declaredMethod.invoke(student, "Mike");
        System.out.println(invoke1);
        System.out.println(student.getName());
    }

2.5 作用、应用场景

反射的作用?

  • 基本作用:可以得到一个类的全部成分然后操作。
  • 可以破坏封装性。
  • 最重要的用途是:适合做lava的框架,基本上,主流的框架都会基于反射设计出一些通用的功能,

在这里插入图片描述

    @Test
    public void saveInfo() throws IOException, IllegalAccessException {
        People tom = new People("Tom", 12);
        Teacher mike = new Teacher("Mike", 21, 22, "123456789");

        //需求:把任意对象的字段名和其对应的值等信息,保存到文件中去
        ObjectFrame.saveInfo(tom);
        ObjectFrame.saveInfo(mike);
    }
package com.reflect;

import java.io.*;
import java.lang.reflect.Field;

public class ObjectFrame {
    //需求:把任意对象的字段名和其对应的值等信息,保存到文件中去
    public static void saveInfo(Object o) throws IllegalAccessException, IOException {
        PrintStream printStream = new PrintStream(new FileOutputStream("src/com/reflect/info.txt", true));
        Class<?> aClass = o.getClass();
        String simpleName = aClass.getSimpleName();
        printStream.println("-------------------------------"+simpleName+"--------------------------------");
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            String value = field.get(o)+"";
            System.out.println(fieldName + ":" + value);
            printStream.println(fieldName + "=" + value);
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习在Debian系统上安装Shadowsocks教程

学习在Debian系统上安装Shadowsocks教程 安装shadowsocks-libev及其所需的依赖启动Shadowsocks服务&#xff1a;如果你想要通过代理本地流量&#xff0c;你可以使用ss-local&#xff1a;启动并设置ss-local&#xff1a;查看状态本地连接 安装shadowsocks-libev及其所需的依赖 …

量化交易为什么独宠Python

“我在学一门叫Python的语言”。“什么是Python&#xff0c;没听说过啊&#xff0c;为什么不学C啊”。这是发生在2014年&#xff0c;上海的一家量化基金&#xff0c;量化研究员和老板之间的对话。 “我想问一下关于Python的课程&#xff0c;什么时候能开班”。“Python啊&#…

数据结构-栈和队列刷题集(长期更新)

文章目录 万能计算器的实现以及源码分析1. leetcode 150 逆波兰表达式求值 万能计算器的实现以及源码分析 /*** 我们尝试写一个完整版的计算器,由于计算机不能很好的识别括号,所以一般要转换为逆波兰表达式求解* 思路解析 :* 1. 输入一个 中缀表达式* 2. 中缀表达式转化为list…

Python 数据结构和算法实用指南(一)

原文&#xff1a;zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 数据结构和算法是信息技术和计算机科学工程学习中最重要的核心学科之一。本书旨在提供数据结构和算法的深入知识&#xff0c;以及编程…

28岁转行嵌入式适合转嵌入式吗?

转行到嵌入式领域是一个很好的选择&#xff0c;特别是如果你对电子技术、嵌入式系统和软硬件交互感兴趣的话。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff0c;给个评论222&a…

信息系统项目管理师0054:运维和服务(4信息系统管理—4.1管理方法—4.1.4运维和服务)

点击查看专栏目录 文章目录 4.1.4运维和服务1.运行管理和控制2.IT服务管理3.运行与监控4.终端侧管理5.程序库管理6.安全管理7.介质控制8.数据管理4.1.4运维和服务 信息系统的运维和服务应从信息系统运行的视角进行整合性的统筹规划,包括对信息系统、应用程序和基础设施的日常控…

C语言的OJ判题机设计与实现

1. 接收判题入参 判题需要作答代码、测试输入和期望输出、编译器名称、时空限制。对于支持special judge的还需要传入是否为sj和sj代码。推荐使用消息队列&#xff0c;应对高并发的比赛情况会比较好。 但是消息队列是异步的&#xff0c;我为了快点实现能提交后在当前页面获得判…

Elasticsearch:(一)ES简介

搜索引擎是什么&#xff1f;在不少开发者眼中&#xff0c;ES似乎就是搜索引擎的代名词&#xff0c;然而这实际上是一种误解。搜索引擎是一种专门用于从互联网中检索信息的技术工具&#xff0c;它主要可以划分为元搜索引擎、全文搜索引擎和垂直搜索引擎几大类。其中&#xff0c;…

AIGC算法1:Layer normalization

1. Layer Normalization μ E ( X ) ← 1 H ∑ i 1 n x i σ ← Var ⁡ ( x ) 1 H ∑ i 1 H ( x i − μ ) 2 ϵ y x − E ( x ) Var ⁡ ( X ) ϵ ⋅ γ β \begin{gathered}\muE(X) \leftarrow \frac{1}{H} \sum_{i1}^n x_i \\ \sigma \leftarrow \operatorname{Var}(…

【中级软件设计师】上午题08-UML(下):序列图、通信图、状态图、活动图、构件图、部署图

上午题08-UML 1 序列图2 通信图3 状态图3.1 状态和活动3.2 转换和事件 4 活动图5 构件图&#xff08;组件图&#xff09;6 部署图 【中级软件设计师】上午题08-UML(上)&#xff1a;类图、对象图、用例图 UML图总和 静态建模&#xff1a;类图、对象图、用例图 动态建模&#xff…

【简单介绍下PostCSS】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

仿真测试的应用领域

仿真测试在各种领域中都有广泛的应用&#xff0c;以下是一些应用最广泛的场景&#xff1a; 工业制造&#xff1a;通过模拟制造过程&#xff0c;可以预测产品的质量和性能&#xff0c;优化生产流程&#xff0c;降低成本。航空航天&#xff1a;飞机、导弹、航天器等的设计和研发…

AWS Key disabler:AWS IAM用户访问密钥安全保护工具

关于AWS Key disabler AWS Key disabler是一款功能强大的AWS IAM用户访问密钥安全保护工具&#xff0c;该工具可以通过设置一个时间定量来禁用AWS IAM用户访问密钥&#xff0c;以此来降低旧访问密钥所带来的安全风险。 工具运行流程 AWS Key disabler本质上是一个Lambda函数&…

如何访问内网?

在互联网万维网上&#xff0c;我们可以轻松访问各种网站和资源。但是&#xff0c;有时我们需要访问局域网内的资源&#xff0c;例如公司内部的文件共享、打印机等。本文将介绍几种方法&#xff0c;帮助您实现访问内网的需求。 内网穿透技术 内网穿透技术是一种通过互联网将局域…

SQL表连接详解:JOIN与逗号(,)的使用及其性能影响

省流版 在这个详细的解释中&#xff0c;我们将深入探讨SQL中表连接的概念&#xff0c;特别是JOIN和逗号&#xff08;,&#xff09;在连接表时的不同用法及其对查询性能的影响。通过实际示例和背后的逻辑分析&#xff0c;我们将揭示在不同场景下选择哪种连接方式更为合适。 1.…

Mysql查询表的结构信息 把列名 数据类型 等变成列数据(适用于生成数据库表结构文档) (二)

书接上文 Mysql查询表的结构信息 把列名 数据类型 等变成列数据(适用于生成数据库表结构文档) (一) 好&#xff0c;怎么生成文档呢&#xff1f;很简单 用navicat 或者sqlyog navicat操作如下 举个例子 如下查询结果 全选查询结果&#xff0c;右键&#xff0c;复制为指标…

什么是神经网络和机器学习?【云驻共创】

什么是神经网络和机器学习&#xff1f; 一.背景 在当今数字化浪潮中&#xff0c;神经网络和机器学习已成为科技领域的中流砥柱。它们作为人工智能的支柱&#xff0c;推动了自动化、智能化和数据驱动决策的进步。然而&#xff0c;对于初学者和专业人士来说&#xff0c;理解神经…

使用CCS软件查看PID曲线

在刚开始学习PID的时候&#xff0c;都需要借助PID的曲线来理解比例&#xff0c;积分&#xff0c;微分这三个参数的具体作用。但是这些曲线生成一般都需要借助上位机软件或者在网页上才能实现。如果是在单片机上调试程序的话&#xff0c;想要看曲线&#xff0c;一般就是通过串口…

[Algorithm][滑动窗口][长度最小的子数组] + 滑动窗口原理

目录 0.滑动窗口原理讲解1.长度最小的子数组1.题目链接2.算法原理讲解3.代码实现 0.滑动窗口原理讲解 滑动窗口&#xff1a;“同向双指针”滑动窗口可处理「⼀段连续的区间」问题如何使用&#xff1f; left 0, right 0进窗口判断 是否出窗口 更新结果 -> 视情况而定 可能…

使用Canal同步MySQL 8到ES中小白配置教程

&#x1f680; 使用Canal同步MySQL 8到ES中小白配置教程 &#x1f680; 文章目录 &#x1f680; 使用Canal同步MySQL 8到ES中小白配置教程 &#x1f680;**摘要****引言****正文**&#x1f4d8; 第1章&#xff1a;初识Canal1.1 Canal概述1.2 工作原理解析 &#x1f4d8; 第2章&…