Junit单元测试
- 黑盒测试:不需要写代码、给输入值、看程序能否输出期望的值
- 白盒测试需要写代码、关注程序的具体执行流程(Junit测试就是白盒测试的一种)
Junit的使用
- 定义一个测试类(测试用例)
- 定义测试方法:可以独立运行
- 给方法加注解@Test
- 判定结果
计算器类
package com.junit;
public class Calculator {
public int add(int a,int b){
return a+b;
}
public int sub(int a,int b){
return a-b;
}
}
测试类
package com.test;
import com.junit.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class CalculatorTest {
@Before
public void init(){
System.out.println("init,,,,,,");
}
@After
public void close(){
System.out.println("after,,,,");
}
@Test
public void testAdd(){
Calculator c=new Calculator();
int result1= c.add(1,5);
Assert.assertEquals(6,result1);
}
@Test
public void testSub(){
Calculator c=new Calculator();
int result2=c.sub(5,6);
Assert.assertEquals(-1,result2);
}
}
反射
- 反射:框架设计的灵魂
- 框架:半成品软件、可以在框架的基础上进行软件开发、简化编码
- 反射:将类的各个组成部分封装为其他对象、这就是反射机制
- 好处:可以在程序运行过程中操作这些对象、可以解耦提高程序的可扩展性
获取字节码class对象的三种方式
- Class.forName("全类名”):将字节码文件加载进内存、返回class对象多用于配置文件将类名定义在配置文件中、读取文件加载类
- 类名.class:通过类名的属性class获取 多用于参数的传递
- 对象.getclass():getclass()方法在object类中定义 多用于对象的获取字节码的方式
- 同一个字节码文件(*.class)在一次程序运行过程中、只会被加载一次、不论通过哪一种方法获取的class对象都是同一个
Person类
package com.domain;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
package com.reflect;
import com.domain.Person;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
Class cls1 = Class.forName("com.domain.Person");
System.out.println(cls1);
Class cls2 = Person.class;
System.out.println(cls1);
Person person=new Person();
Class cls3=person.getClass();
System.out.println(cls3);
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
}
}
class对象功能
- 获取功能:获取成员变量、获取构造方法、获取成员方法、获取类名
Person类
package com.domain;
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
'}';
}
public void eat(){
System.out.println("eat......");
}
public void eat(String food){
System.out.println("eat......"+food);
}
}
ReflectDemo2类
package com.reflect;
import com.domain.Person;
import java.lang.reflect.Field;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
Class personClass = Person.class;
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("==================");
Field a = personClass.getField("a");
Person person=new Person();
Object vaule1 = a.get(person);
System.out.println(vaule1);
a.set(person,"王文超");
System.out.println(person);
System.out.println("===================");
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
Field d = personClass.getDeclaredField("d");
d.setAccessible(true);
Object value2 = d.get(person);
System.out.println(value2);
}
}
ReflectDemo3类
package com.reflect;
import com.domain.Person;
import java.lang.reflect.Constructor;
public class ReflectDemo3 {
public static void main(String[] args) throws Exception {
Class personClass = Person.class;
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
Object person = constructor.newInstance("张三", 23);
System.out.println(person);
System.out.println("===================");
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor1);
Object person1 = constructor1.newInstance();
System.out.println(person1);
Object person2 = personClass.newInstance();
System.out.println(person2);
}
}
ReflectDemo4类
package com.reflect;
import com.domain.Person;
import java.lang.reflect.Method;
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
Class personClass = Person.class;
Method eat_method = personClass.getMethod("eat");
Person p=new Person();
eat_method.invoke(p);
Method eat_method2 = personClass.getMethod("eat", String.class);
eat_method2.invoke(p,"饭");
System.out.println("=========================");
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
String name = method.getName();
System.out.println(name);
}
String classname = personClass.getName();
System.out.println(classname);
}
}
反射——案例
写一个”框架“、可以帮我们创建任意类的对象、并且执行其中的任意方法 前提:不能改变该类的任何代码
实现:1、配置文件 。2、反射 步骤 1、将需要创建对象的全类名和需要执行的方法定义在配置文件中 2、在程序中加载读取配置文件 3、使用反射技术来加载类文件进内存 4、创建对象 5、执行方法
Student类
package com.domain;
public class Student {
public void sleep(){
System.out.println("sleep......");
}
}
pro.properties配置文件
className=com.domain.Student
methodName=sleep
ReflectTest类
package com.reflect;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectTest {
public static void main(String[] args) throws Exception {
Properties pro=new Properties();
ClassLoader classLoader = ReflectTest.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
pro.load(is);
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
Class cls = Class.forName(className);
Object obj = cls.newInstance();
Method method = cls.getMethod(methodName);
method.invoke(obj);
}
}
注解
概念:说明程序的。给计算机看的 注释:用文字描述程序的。给程序员看的
jdk内置注解 @Override :检测被该注解标注的方法是否是继承自父类(接口)的 @ @Deprecated:该注解标注的内容、表示已过时 @SuppressWarnings:压制警告 —一般传递参数all—@SuppressWarnings(“all”)
package com.annotation;
import java.util.Date;
@SuppressWarnings("all")
public class AnnoDemo2 {
@Override
public String toString(){
return super.toString();
}
@Deprecated
public void show1(){
}
public void show2(){
}
public void demo(){
show1();
Date date=new Date();
}
}
自定义注解 格式 元注解 public @interface 接口名{属性列表;}
本质:注解本质上就是一个接口、该接口默认继承Annotation接口
属性:接口中的抽象方法 1、属性的返回值类型:基本数据类型、String、枚举、注解、以上类型的数组 2、定义了属性、使用时需要给属性赋值 如果使用default关键字给属性默认初始化值、则使用时可以不进行属性的赋值-------如果只有一个属性、并且属性的名称是value时,可以省略属性名称、直接定义值—数组赋值时、使用{}包裹、如果数组只有一个值、可以省略{}
Calculator类
package com.demo;
public class Calculator {
@Check
public void add(){
System.out.println("1+0="+(1+0));
}
@Check
public void sub(){
System.out.println("1-0="+(1-0));
}
@Check
public void mul(){
System.out.println("1*0="+(1*0));
}
@Check
public void div(){
System.out.println("1/0="+(1/0));
}
public void show(){
System.out.println("================");
}
}
Check注解
package com.demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check {
}
TestCheck测试类
package com.demo;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
public class TestCheck {
public static void main(String[] args) throws IOException {
Calculator calculator=new Calculator();
Class cls = calculator.getClass();
Method[] methods = cls.getMethods();
int number=0;
BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
for (Method method : methods) {
if (method.isAnnotationPresent(Check.class)){
try {
method.invoke(calculator);
}catch (Exception e){
number++;
bw.write(method.getName()+"方法出异常了");
bw.newLine();
bw.write("异常的名称:"+e.getCause().getClass().getSimpleName());
bw.newLine();
bw.write("异常的原因:"+e.getCause().getMessage());
bw.newLine();
bw.write("=========================");
bw.newLine();
}
}
}
bw.write("本次测试一共出现"+number+"次异常");
bw.flush();
bw.close();
}
}
|