Junit单元测试
黑盒测试:
白盒测试:
需要写代码的,看程序执行的具体过程—-如:Junit单元测试

不能传参
@Before @After

package com.igeek_01;/*** @author Lynn* @create 2020-12-18-9:29*/import org.junit.After;import org.junit.Before;import org.junit.Test;/*** junit测试适用于代码的测试,是单元测试用于替代main方法*/public class JunitTest01 {@Testpublic void test01(){System.out.println("运行1通过");}@Testpublic void test02(){System.out.println("运行2通过");}/*** @Before* @After*/@Beforepublic void Before(){System.out.println("在@Test方法之前运行");}@Afterpublic void after(){System.out.println("在@Test方法之后运行");}}运行结果:在@Test方法之前运行运行1通过在@Test方法之后运行在@Test方法之前运行运行2通过在@Test方法之后运行

package com.igeek_01;/*** @author Lynn* @create 2020-12-18-10:00*//*** Junit测试类也是一个普通的类,也可以实例化*/public class JunitTest02 {public static void main(String[] args) {//实例化这个类JunitTest01 test01=new JunitTest01();test01.test01();test01.after();test01.Before();}}运行结果:运行1通过在@Test方法之后运行在@Test方法之前运行
反射机制—reflect
定义:
** ****是在运行状态中,在任意一个类中,都能够知道他的所有的属性和方法;对于任意一个对象,都能够调用他的所有的属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称之为java语言的反射机制。**<br />** 每一个类,都会被appclassloader加载到方法区,生成Class类型的对象**<br />
获取类对象的方法
1.使用类:Class clazz=Student.class;
2.使用全类名(包名.类名)—比较常用—安全
Class clazz=Class.forName(“com.igeek_02.Student”);
3.使用对象:
Student s=new Student();
Class clazz=s.getClass();

package com.igeek_02;/*** @author Lynn* @create 2020-12-18-10:11*//*** 实体类* 用于测试反射*/public class Student {//字段--属性public int id;private String name;//构造public Student() {super();}public Student(int id, String name) {super();this.id = id;this.name = name;}//方法public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}//私有方法--用于测试private void setName(String name) {this.name = name;}//静态方法public static int getCount(int c){return c*10;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +'}';}}
package com.igeek_02;/*** @author Lynn* @create 2020-12-18-10:04*/import org.junit.Test;/*** java反射机制** 目前讲反射是讲解反射的使用*/public class ReflectDemo {//单元测试@Testpublic void test1(){//已知明确的类型,获取Class对象Class clazz=Student.class;System.out.println(clazz);//class com.igeek_02.Student}@Testpublic void test2(){//已知对象,获取Class对象Student s=new Student();Class clazz=s.getClass();//getClass()是顶级父类Object中的方法System.out.println(clazz);//class com.igeek_02.Student}@Testpublic void test3() throws ClassNotFoundException {//完全限定名(包名.类名),获取Class对象--比较常用--安全String className="com.igeek_02.Student";//forName()返回这个地址值所对应的类Class clazz=Class.forName(className);System.out.println(clazz);//class com.igeek_02.Student}//测试结果:通过不同的反射获取的对象是同一个!!@Testpublic void test4() throws ClassNotFoundException {//第一种Class clazz1=Student.class;//第二种Student s=new Student();Class clazz2=s.getClass();//第三种String className="com.igeek_02.Student";Class clazz3=Class.forName(className);//比较System.out.println(clazz1==clazz2);System.out.println(clazz1==clazz3);System.out.println(clazz3==clazz2);}}
package com.igeek_02;/*** @author Lynn* @create 2020-12-18-10:31*/import org.junit.Test;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;/*** 通过java的反射机制构建对象的测试*/public class ReflectDemo2 {@Testpublic void test01() throws IllegalAccessException, InstantiationException {//类中有无参构造Class clazz=Student.class;Object obj=clazz.newInstance();//默认调用的是无参的--创建实例System.out.println(clazz);//class com.igeek_02.StudentSystem.out.println(obj);//Student{id=0, name='null'}--// 当前的object进行了向下转型给了反射获取到的类Student}@Testpublic void test02() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class类中的构造函数对象Class clazz=Student.class;//获取到有参构造函数Constructor con= clazz.getConstructor(int.class, String.class);Object obj = con.newInstance(20, "Tom");System.out.println(obj);//Student{id=20, name='Tom'}}//演示普通的方式实例化对象做不到的事情@Testpublic void test03(){Student s=new Student();s.setId(1);// s.setName();//不能进行name赋值,因为方法是私有的System.out.println(s);//Student{id=1, name='null'}}}
package com.igeek_02;/*** @author Lynn* @create 2020-12-18-11:14*/import com.sun.deploy.xml.XMLable;import org.junit.Test;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/*** 反射处理静态方法*/public class ReflectDemo3 {@Testpublic void test01(){//静态方法的调用--普通int count=Student.getCount(10);System.out.println(count);//100}@Testpublic void test02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {//静态方法的调用--利用反射机制处理//1.创建ClassString className="com.igeek_02.Student";Class clazz=Class.forName(className);//2.调用静态方法Method hetCount = clazz.getMethod("getCount", int.class);//3.根据类型传参--invoke方法表示映射,这里因为不需要实例,所以可以传参nullObject obj=hetCount.invoke(null,2);System.out.println(obj);//20}}
获取字段—Field—-获取值和修改值



package com.igeek.ziduan;import org.junit.Test;import java.lang.reflect.Field;/*** @author Lynn* @create 2020-12-21-9:31*/public class FieldTest01 {//利用反射机制处理公共字段@Testpublic void test2() throws Exception{//获取类Class clazz=Class.forName("com.igeek.ziduan.Student");//创建实例对象Object o = clazz.newInstance();//处理字段Field id = clazz.getField("id");id.set(o,30);System.out.println(o);//通过key获取值Object o1 = id.get(o);System.out.println(o1);}//利用反射机制处理私有字段@Testpublic void test3() throws Exception{//获取类Class clazz=Class.forName("com.igeek.ziduan.Student");//创建实例对象Object o = clazz.newInstance();//处理字段Field name = clazz.getDeclaredField("name");System.out.println(name);//private java.lang.String com.igeek.ziduan.Student.name//打破私有权限name.setAccessible(true);name.set(o,"Lynn");System.out.println(o);//Student{id=0, name='Lynn'}//通过key获取值Object o1 = name.get(o);System.out.println(o1);//Lynn}}
获取方法—-invoke—用来调用
构造方法—-核心是用来构造对象的—new对象
讲解Properties使用
映射—在properties中使用Map—通过键找到值
package com.igeek.properties;import org.junit.Test;import java.io.*;import java.util.Properties;/*** @author Lynn* @create 2020-12-21-9:47*/public class PropertiesDemo {//第一种方式:添加内容,使用Map中的方法--put@Testpublic void test1() throws IOException {//保存properties的数据到流中--void store(OutputStream out,String content)Properties prop=new Properties();prop.put("id","100");prop.put("name","Lynn");prop.store(new FileOutputStream("t.txt"),"要写入的内容");//内容的Unicode}//读取流--void load(InputStream in)@Testpublic void test2() throws IOException {Properties prop=new Properties();//读取prop.load(new FileInputStream("t.txt"));System.out.println(prop);//{name=Lynn, id=100}//String id = prop.getProperty("id");System.out.println(id);String name = prop.getProperty("name");System.out.println(name);}//第二种方式:使用properties方法设置数据--setProperty@Testpublic void test3() throws IOException {Properties prop=new Properties();prop.setProperty("id","20");prop.setProperty("name","Cheery");prop.store(new FileOutputStream("t2.txt"),"过");// System.out.println(prop);//{name=Cheery, id=20}//通过key获取值String id = prop.getProperty("id");String name = prop.getProperty("name");/*String id = prop.getProperty("id1");System.out.println(id);*///如果key炸不到则返回null// System.out.println(name);}//读取@Testpublic void test4() throws IOException {Properties prop=new Properties();prop.load(new FileInputStream("t2.txt"));System.out.println(prop.get("id"));System.out.println(prop.get("name"));}}
配置文件—利用properties类实现不修改源码的基础上处理数据
注意:从**properties**中获取的都是字符串类型


package com.igeek.config;/*** @author Lynn* @create 2020-12-21-10:32*/import org.junit.Test;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.util.Properties;/*** 利用properties类实现不修改源码的基础上处理数据*/public class ConfigTest {@Testpublic void test1(){//测试学生和老师的对象Student s=new Student(54,"Lynn");System.out.println(s);Teacher t=new Teacher(54,"Lynn");System.out.println(t);}/***从配置文件className中读取要获取哪一个类* 好处:获取哪个类直接修改配置文件,不需要修改源代码* 1.首先要获取配置文件*/@Testpublic void test2() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//从className中读取类名Properties prop=new Properties();//加载配置文件并且读取prop.load(new FileReader("className.properties"));//根据key获取valueString className= prop.getProperty("className");System.out.println(className);//com.igeek.config.Teacher//创建类的实例--反射Class clazz=Class.forName(className);//找到该类的构造器--有参Constructor constructor = clazz.getConstructor(int.class, String.class);//利用构造函数处理数据Object o = constructor.newInstance(54, "Lynn");System.out.println(o);}/*** 从配置文件data.properties中读取数据并且填入实例**/@Testpublic void test3() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//从className中读取类名Properties prop=new Properties();//加载配置文件并且读取prop.load(new FileReader("className.properties"));//根据key找到valueString className = prop.getProperty("className");//创建实例Class clazz=Class.forName(className);//构造函数中进行处理//1.从data配置文件中获取数据Properties prop_Data=new Properties();prop_Data.load(new FileReader("data.properties"));String v_id = prop_Data.getProperty("id");String v_name = prop_Data.getProperty("name");System.out.println(v_id+v_name);//将数据写入对象Constructor constructor = clazz.getConstructor(int.class, String.class);//从properties中获取的都是字符串类型,所以要强制转换为int类型--parseIntObject o = constructor.newInstance(Integer.parseInt(v_id),v_name);System.out.println(o);}}
BeanUtils工具类


package com.igeek.user;import org.apache.commons.beanutils.BeanUtils;import org.junit.Test;import java.lang.reflect.InvocationTargetException;/*** @author Lynn* @create 2020-12-21-11:27*/public class BeanUtilsDemo {//常规的--调用get/set方法@Testpublic void test1(){User use=new User();use.setUid("u001");use.setUsername("Lynn");System.out.println(use);//User{uid='u001', username='Lynn', password='null', hobbies=null, age=0}}//使用BeanUtils工具进行封装--底层调用的还是get/set方法@Testpublic void test2() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {User use=new User();//BeanUtils.setProperty(use,"uid","u002");//封装配置文件BeanUtils.setProperty(use,"username","Cheery");BeanUtils.setProperty(use,"password","123");System.out.println(use);//User{uid='u002', username='Cheery', password='123', hobbies=null, age=0}//获取值System.out.println(BeanUtils.getProperty(use, "username"));//Cheery//如果找不到会报错/*System.out.println(BeanUtils.getProperty(use, "username1"));//java.lang.NoSuchMethodException: Unknown property 'username1' on class 'class com.igeek.user.User'*/}}

BeanUtils**类的populate(Object bean, Map
将Map数据封装到指定Javabean中,一般用于将表单的所有数据封装到javabean。**
package com.igeek.user;import org.apache.commons.beanutils.BeanUtils;import org.junit.Test;import java.lang.reflect.InvocationTargetException;import java.util.HashMap;import java.util.Map;/*** @author Lynn* @create 2020-12-21-11:27*//*** BeanUtils的方法讲解*/public class BeanUtilsDemo1 {//使用populated方法进行填充数据方法1@Testpublic void test1() throws InvocationTargetException, IllegalAccessException {//1.模拟数据,创建map,填充所需要的数据Map<String,String[]> map=new HashMap<>();map.put("uid",new String[]{"u007"});map.put("username",new String[]{"王嘉尔"});map.put("password",new String[]{"123"});//2.使用populate方法进行填充User user=new User();BeanUtils.populate(user,map);System.out.println(user);}//使用BeanUtils工具进行封装--底层调用的还是get/set方法@Testpublic void test2() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {Map<String,String[]> map=new HashMap<>();map.put("uid",new String[]{"u008"});//底层:就是调用了setUsername方法map.put("username",new String[]{"郭靖","黄蓉"});map.put("password",new String[]{"123"});map.put("hobbies",new String[]{"降龙十八掌","碧海潮生曲","打狗十八式"});map.put("age",new String[]{"45"});//2.使用populate方法进行填充/*** 可以指定属性,统一进行填充,需要的类型是数组[]* 如果属性不是数组,将使用map.value表示数组中的第一个数据--* 黄蓉不是第一个数据,所以不见了* BeanUtils支持的类型:基本类型和基本类型对应的包装类,* 自动将字符串转换为基本类型--自己做的*/User user=new User();BeanUtils.populate(user,map);System.out.println(user);//User{uid='u008', username='郭靖', password='123', hobbies=[降龙十八掌, 碧海潮生曲, 打狗十八式], age=45}}}
自定义BeanUtils工具类

package com.igeek.user;import org.apache.commons.beanutils.BeanUtils;import org.junit.Test;import java.lang.reflect.InvocationTargetException;import java.util.HashMap;import java.util.Map;/*** @author Lynn* @create 2020-12-21-11:27*//*** 自定义BeanUtils工具类*/public class BeanUtilsDemo2 {//自动填充public static void populate(Object bean,Map<String,String[]> properties){try {BeanUtils.populate(bean,properties);} catch (Exception e) {throw new RuntimeException(e);}}//自动填充的方法,并且返回bean对象public static Object populate(Class beanClass,Map<String,String[]> properties){try {Object bean = beanClass.newInstance();//BeanUtils.populate(bean,properties);return bean;} catch (Exception e) {throw new RuntimeException(e);}}}
package com.igeek.user;/*** @author Lynn* @create 2020-12-21-15:07*/import org.apache.commons.beanutils.BeanUtils;import org.junit.Test;import java.util.HashMap;import java.util.Map;/*** 测试自定义的方法--populate*/public class MyBeanUtilsTest {//测试没有返回值的方法@Testpublic void test1(){Map<String,String[]> map=new HashMap<>();map.put("uid",new String[]{"u007"});map.put("username",new String[]{"王嘉尔"});map.put("password",new String[]{"123"});//2.使用populate方法进行填充User user=new User();BeanUtilsDemo2.populate(user,map);System.out.println(user);}//测试有返回值的方法@Testpublic void test2(){Map<String,String[]> map=new HashMap<>();map.put("uid",new String[]{"u007"});map.put("username",new String[]{"王嘉尔"});map.put("password",new String[]{"123"});//2.使用populate方法进行统一的填充--向下转型--因为自己封装的方法返回的是Object类型,//所以如果要获取,指定的类型就必须向下转型User user = (User) BeanUtilsDemo2.populate(User.class, map);//向下转型System.out.println(user);}}
带泛型的自定义工具类
package com.igeek.MyBeanUtils;/*** @author Lynn* @create 2020-12-21-15:53*/import org.apache.commons.beanutils.BeanUtils;import org.apache.commons.beanutils.BeanUtilsBean;import java.lang.reflect.InvocationTargetException;import java.util.Map;/*** MyBeanUtils泛型使用*/public class MyBeanUtils {/**** @param beanClass* @param properties* @return** Class<T>此时这个T就是一个变量,在运行的时候,接收具体的类型。例如:User* 变量必须先定义再使用* 泛型变量的定义方式,修饰符<变量名> 返回值*/public static <T> T populate(Class<T> beanClass, Map<String,String[]> properties){try {//1.使用反射机制实例化T bean=beanClass.newInstance();//2.填充数据BeanUtils.populate(bean,properties);//返回数据return bean;} catch (Exception e) {throw new RuntimeException(e);}}}
package com.igeek.MyBeanUtils;/*** @author Lynn* @create 2020-12-21-16:00*/import com.igeek.user.User;import org.junit.Test;import java.util.HashMap;import java.util.Map;/*** 测试自定义泛型的BeanUtils*/public class MyBeanUtilsTest {@Testpublic void test1(){Map<String,String[]> map=new HashMap<>();map.put("uid",new String[]{"u007"});map.put("username",new String[]{"王嘉尔","王一博"});map.put("password",new String[]{"123"});//数据填充--用到了泛型User user = MyBeanUtils.populate(User.class, map);System.out.println(user);}}
xml文件
DOM4j工具

package com.igeek.Dom4j;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import java.util.List;/*** @author Lynn* @create 2020-12-23-10:34*/public class DOM4jDemo {//测试DOM4j解析@Testpublic void testParse() throws DocumentException {//1.获取核心类--import org.dom4j.io.SAXReader;SAXReader saxReader=new SAXReader();//2.获取整个xml文档--import org.dom4j.Document;Document document= saxReader.read("beans.xml");//3.获取所有beans--import org.dom4j.DocumentException;Element rootElement= document.getRootElement();//4.获取所有的子节点List<Element> allBeanElement = rootElement.elements("bean");//遍历集合for (Element beanEle:allBeanElement){//根据自己设定的属性进行解析--beanString id=beanEle.attributeValue("id");String className=beanEle.attributeValue("className");System.out.println("bean的属性:"+id+","+className);//获取子元素的propertyList<Element> property = beanEle.elements("property");for (Element propEle:property){String name=propEle.attributeValue("name");String value=propEle.attributeValue("value");System.out.println("property的属性:"+name+","+value);}}// System.out.println();//换行}}
综合案例1—工厂模式



package com.igeek.Dom4j_02;/*** @author Lynn* @create 2020-12-23-11:23*/import java.util.Properties;/*** javaBean的配置对象** BeanConfig文件用于将对应的xml的配置项,解析封装到对象中* 属性:id,className,property** 当前这个实体类的实例化beans.xml文件,相当于是一个属性配置的中转站* 后面进行的操作都是通过中转站处理的*/public class BeanConfig {private String id;private String className;//用于解析当前的这个bean中的所有的属性,所以直接创建一个properties的对象private Properties props=new Properties();public BeanConfig(){}public BeanConfig(String id, String className, Properties props) {this.id = id;this.className = className;this.props = props;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public Properties getProps() {return props;}public void setProps(Properties props) {this.props = props;}@Overridepublic String toString() {return "BeanConfig{" +"id='" + id + '\'' +", className='" + className + '\'' +", props=" + props +'}';}}
package com.igeek.Dom4j_02;/*** @author Lynn* @create 2020-12-23-14:00*/import org.apache.commons.beanutils.BeanUtils;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.junit.Test;import java.util.HashMap;import java.util.List;import java.util.Map;/*** 设计模式:23种,常用的有:* 单例模式,工厂模式,代理模式,模板模式...** 工厂模式:*/public class BeanFactory {//1.提供map存放beans.xml中的配置文件内容,使用map,建议使用静态处理--好处是只要加载一次private static Map<String,BeanConfig> cache=new HashMap<>();//静态块进行处理数据添加--直接使用静态块一次性加载static {try {//SAXReader saxReader = new SAXReader();Document document = saxReader.read("beans.xml");//获取根元素Element rootElement = document.getRootElement();//获取所有的bean元素,当前子元素不止一个,使用listList<Element> allBeanElement = rootElement.elements("bean");//遍历集合for (Element beanEle : allBeanElement) {//外层的bean的属性String id = beanEle.attributeValue("id");String className = beanEle.attributeValue("className");//创建BeanConfig,并且封装id和classNameBeanConfig beanConfig = new BeanConfig();beanConfig.setId(id);beanConfig.setClassName(className);//获取子标签propertyList<Element> allPropertyElement = beanEle.elements("property");for (Element propEle : allPropertyElement) {String name = propEle.attributeValue("name");String value = propEle.attributeValue("value");//将name和value保存到BeanConfig中--先拿到propertybeanConfig.getProps().setProperty(name, value);}//内层for循环//将封装好的数据保存到map集合cache.put(id, beanConfig);}//外层for循环--endSystem.out.println("初始化数据:" + cache);} catch (Exception e) {throw new RuntimeException(e);}}//public static Object getBean(String beanId){BeanConfig beanConfig=cache.get(beanId);//判断这个对象是否合法if (beanConfig==null){throw new RuntimeException("获得的对象["+beanId+"]不存在");}//如果存在--通过反射机制进行获取try {String className = beanConfig.getClassName();Class clazz=Class.forName(className);//获取实例对象Object obj = clazz.newInstance();//循环解析--BeanUtils//stringPropertyNames()方法是Properties的api中提供的,// 作用是获取到属性名字的字符串类型for (String name:beanConfig.getProps().stringPropertyNames()){//每遍历到一个name,就返回name对应的valueString value=beanConfig.getProps().getProperty(name);//使用BeanUtils封装数据BeanUtils.setProperty(obj,name,value);}return obj;}catch(Exception e){throw new RuntimeException(e);}}}
package com.igeek.Dom4j_02;/*** @author Lynn* @create 2020-12-23-14:39*/import org.junit.Test;/*** 测试类*/public class XMLTEst {@Testpublic void test(){//通过实例化数据的方法获取User user=(User)BeanFactory.getBean("userId01");System.out.println(user);Book book=(Book) BeanFactory.getBean("book02");System.out.println(book);}}

