单元测试
对最小功能单元------方法编写代码,进行测试
Junit单元测试框架
可用来对方法进行测试,是第三方公司开源的
- 优点:
可灵活编写测试代码,可针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立
不需要程序员分析测试的结果,会自动生成测试报告
java
/**
* 字符串工具类
*/
public class StringUtil {
public static void printNumber(String name){
if(name==null){
System.out.println("请输入字符串");
return;
}
System.out.println("长度是:"+name.length());
}
/**
* 求字符串最大索引
*/
public static int getMaxIndet(String data){
if(data==null || "".equals(data)){
return -1;
}
return data.length()-1;
}
}
java
// 测试类:JUnit单元测试框架,测试StringUtil类
public class StringUtilTest {
//测试方法:公开public,无参,无返回值
//测试方法必须加上@Test注解(核心步骤)
@Test
public void testPrintNumber(){
//测试步骤
StringUtil.printNumber("张三aaa");//5
//测试用例
StringUtil.printNumber("");
StringUtil.printNumber(null);
}
@Test
public void testGetMaxIndet(){
int max = StringUtil.getMaxIndet("abcdef");
//测试用例
int max1 = StringUtil.getMaxIndet("");
int max2 = StringUtil.getMaxIndet(null);
//断言测试:测试结果与预期结果是否一致
Assert.assertEquals("本轮测试失败,业务获取最大索引有问题",5,max);
Assert.assertEquals("本轮测试失败,业务获取最大索引有问题",-1,max1);
Assert.assertEquals("本轮测试失败,业务获取最大索引有问题",-1,max2);
}
}
反射
反射:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器)
第一步:获得class对象
java
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//掌握反射第一步操作:获取类的class对象
//1、获取类本身:类名.class
Class c1 = Student.class;
System.out.println(c1);
//2、获取类本身:Class.forName("全类名")
Class c2 = Class.forName("com.it06.junit_reflect_annotation_proxy.demo2reflect.Student");
System.out.println(c2);
System.out.println(c1==c2);
//3、获取对象本身:对象.getClass()
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c3);
System.out.println(c1==c3);
}
}
第二步:获取类中的成分,并进行操作

java
public class ReflectDemo2 {
@Test
public void getClassInfo() {
//获取类中的信息
//反射第一步:获取类本身
Class c1 = Student.class;
System.out.println(c1.getName());//类名的全类名 com.it06.junit_reflect_annotation_proxy.demo2reflect.Student
System.out.println(c1.getSimpleName());//类名 Student
}
//2、获取类的构造器对象,并进行操作
@Test
public void getConstructor() throws Exception {
Class c1 = Dog.class;
//获取构造器对象
Constructor[] cons = c1.getDeclaredConstructors();
for (Constructor c : cons) {
System.out.println(c.getName() +"("+ c.getParameterCount()+")");
}
//3、获取单个构造器对象
Constructor con = c1.getDeclaredConstructor();
System.out.println(con.getName() +"("+ con.getParameterCount()+")");
Constructor con2 = c1.getDeclaredConstructor(String.class,int.class);//2个参数的有参构造器
System.out.println(con2.getName() +"("+ con2.getParameterCount()+")");
//4、获取构造器的作用依然是创建对象
//暴力反射:暴力反射,忽略访问权限修饰符
con.setAccessible(true);//绕过访问权限
Dog d1 = (Dog) con.newInstance();
System.out.println(d1);
Dog d2 = (Dog) con2.newInstance("小花",2);
System.out.println(d2);
}
//3、获取类的成员变量对象,并进行操作
@Test
public void getField() throws Exception {
//获取Class对象
Class c1 = Dog.class;
//获取成员变量对象
Field[] field = c1.getDeclaredFields();
for (Field f : field) {
System.out.println(f.getName() +"("+ f.getType().getName()+")");
}
//获取单个成员变量对象
Field f = c1.getDeclaredField("sex");
System.out.println(f.getName() +"("+ f.getType().getName()+")");
Field f2 = c1.getDeclaredField("age");
System.out.println(f2.getName() +"("+ f2.getType().getName()+")");
//4、获取成员变量的作用依然是取值和赋值
Dog d1 = new Dog( "小花", 2);
f.setAccessible(true);//绕过访问权限
f.set(d1, "female");
System.out.println(d1);
String sex = (String) f.get(d1);
System.out.println(sex);
}
//4、获取类的成员方法对象,并进行操作
@Test
public void getMethod() throws Exception {
//获取Class对象
Class c1 = Dog.class;
//获取成员方法对象
Method[] methods = c1.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m.getName() +"("+ m.getParameterCount()+")");
}
//获取单个成员方法对象
Method m = c1.getDeclaredMethod("show");//获取无参数的show方法
Method m2 = c1.getDeclaredMethod("show",String.class);//获取有参数的show方法
System.out.println(m.getName() +"("+ m.getParameterCount()+")");
System.out.println(m2.getName() +"("+ m2.getParameterCount()+")");
//5、获取成员方法的作用依然是调用方法
Dog d1 = new Dog( "小花", 2);
m.setAccessible(true);
Object rs1 = m.invoke(d1);//唤醒d1的show方法执行,相当于d1.show()
System.out.println(rs1);
Object rs2 = m2.invoke(d1, "小黑");
System.out.println(rs2);
}
}
作用、应用场景
- 基本作用:得到一个类的全部成分然后操作
- 破坏封装性
- 绕过泛型的约束
- 最重要的用途:做java的框架,基本主流框架都会基于反射设计一些通用功能。
使用反射做一个简易版框架
需求:
对任意一个对象,该框架可以把对象字段名和对应的值保存到文件中
步骤
1、定义一个方法接收任何对象
2、每收到一个对象 ,使用反射获取该对象的class对象,然后获取全部的成员变量
3、遍历成员变量,然后提取成员变量在该对象中的具体值
4、把成员变量名和值写道文件中
java
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
//搞清反射的应用:做框架的通用技术
Dog dog = new Dog("张三", 5);
saveObject(dog);
//创建学生对象
Student s = new Student( "方源", 500,"炼蛊");
saveObject(s);
//创建老师对象
Teacher t = new Teacher("星宿", 20000, "占卜",5000,"天庭","female");
saveObject(t);
}
}
java
public class SaveObjectFrameWork {
//保存任意对象的静态方法
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("D:\\javacode\\javaseaimax\\product/src/obj.txt", true));
//obj可能是任意对象
//只有反射能知道对象有多少字段
//1、获取Class对象
Class c1 = obj.getClass();
String name = c1.getSimpleName();
ps.println("============="+name+"================");
//2、获取Class对象所有字段
Field[] fields = c1.getDeclaredFields();
//3、遍历字段
for (Field f : fields) {
//4、获取字段名称
String fieldName = f.getName();
//5、获取字段值
f.setAccessible(true);
Object fieldValue = f.get(obj) + "";
//6、打印到文件
ps.println(fieldName + ":" + fieldValue);
}
ps.close();
}
}