1 单元测试(白盒测试)
-
测试类
-
独立运行(返回值void 、参数void)
-
方法添加@Test
-
被测试的类
package com.xhh.calc.calcClass;
/**
* @author : xhh
* @email : xhh0608@foxmail.com
* @date : 2021.10.4
*/
public class Calc {
public int addNum(int a, int b){
return a + b;
}
public int subNum(int a, int b){
return a - b;
}
}
- 测试类
package com.xhh.calc.test;
import com.xhh.calc.calcClass.Calc;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author : xhh
* @email : xhh0608@foxmail.com
* @date : void
*/
public class CalcTest {
@Before
public void init(){
System.out.println("init 申请资源,如IO等等");
}
@After
public void close(){
System.out.println("close .. 释放资源");
}
@Test
public void testAdd(){
Calc calc = new Calc();
int ret = calc.addNum(1, 2);
Assert.assertEquals(ret, 3);
}
@Test
public void testSub(){
Calc calc = new Calc();
// 断言
int ret = calc.subNum(1, 2);
Assert.assertEquals(ret, -1);
}
}
/**
init 申请资源,如IO等等
close .. 释放资源
init 申请资源,如IO等等
close .. 释放资源
*/
2 反射
类对象
- 成员变量:Field[] fields
- 构造方法:Constructor[] cons
- 成员方法:Method[] methods
2.1 获取Class对象的方式
// [1] 源码阶段
Class.forName("类名");
// [2] 类对象阶段
类名.class
// [3] 通过对象
对象.getClass()
package com.xhh.reflection;
import com.xhh.reflection.domain.Person;
/**
* @author : xhh
* @email : xhh0608@foxmail.com
* @date : void
*/
public class GetClass {
public static void main(String[] args) throws Exception {
// [1] 源码阶段
Class<?> cls1 = Class.forName("com.xhh.reflection.domain.Person");
System.out.println(cls1);
// [2] 类对象阶段
Class<Person> cls2 = Person.class;
// [3] 通过对象
Person xhh = new Person("xhh", 18);
Class<? extends Person> cls3 = xhh.getClass();
System.out.println(cls1 == cls2); // true
System.out.println(cls1 == cls3); // true
}
}
2.2 使用Class
- Person
package com.xhh.reflection.domain;
public class Person {
public Person(){}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public void methodInfo(){
System.out.println("methodInfo ...");
}
private String name;
private Integer age;
public String info = "xhh123456";
}
package com.xhh.reflection;
import com.xhh.reflection.domain.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class GetClass {
public static void main(String[] args) throws Exception {
// 源码阶段
Class<?> cls1 = Class.forName("com.xhh.reflection.domain.Person");
System.out.println(cls1);
// [*]获取构造器
// Person()
Constructor<?> cons1 = cls1.getConstructor();
// Person(String name, Integer age)
Constructor<?> cons2 = cls1.getConstructor(String.class, Integer.class);
// 创建对象
Person mcy = (Person)cons2.newInstance("mcy", 123);
System.out.println(mcy);
// [*]获取方法
Method methodInfo = cls1.getMethod("methodInfo");
// 执行方法
methodInfo.invoke(mcy);
// [*]获取(public)成员变量 设置值和得到值
Field info = cls1.getField("info");
info.setAccessible(true); // 暴力反射 可以访问所以权限类型
info.set(mcy, "mcy----newValue"); // set
Object o = info.get(mcy); // get
System.out.println(o);
}
}
2.3 案例
- Cat
package com.xhh.reflection;
public class Cat {
public void catMethod(){
System.out.println("miao miao miao ...");
}
}
- Dog
package com.xhh.reflection;
public class Dog {
public void dogMethod(){
System.out.println("wang wang wang ...");
}
}
- pro.properties
#className=com.xhh.reflection.Cat
className=com.xhh.reflection.Dog
methodName=dogMethod
- Main
package com.xhh.reflection;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.Properties;
public class TestPro {
public static void main(String[] args) throws Exception {
// [1] 配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("./src/pro.properties"));
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
// [2] 加载字节码类
Class<?> cls = Class.forName(className);
Object obj = cls.newInstance();
Method method = cls.getMethod(methodName);
// [3] 执行方法
method.invoke(obj);
}
}
3 注解
3.1 内置三种注解
package com.xhh.reflection;
// [3] 压制所有警告
@SuppressWarnings("all")
public class Annotation_ {
// [1] 重写父类方法
@Override
public String toString(){
return super.toString();
}
// [2] 标记过时 不推荐使用
@Deprecated
public void showVersion1(){
// 过时
}
public void showVersion2(){
// 新方法
}
}
3.2 自定义注解
- 格式
public @interface XhhAnno{
}
- 元注解
package com.xhh.reflection;
import java.lang.annotation.*;
/**
* @author : xhh
* @email : xhh0608@foxmail.com
* @date : void
*/
@Target(value = {ElementType.TYPE, ElementType.METHOD}) // 作用于类和方法
@Retention(RetentionPolicy.RUNTIME) // 运行时(自定义一般用这个)
@Documented // 注释可以被抽取到Doc文档中
@Inherited // 自动可以被子类继承
public @interface Anno_ {
}
- 案例(加载配置文件)
注解
package com.xhh.reflection;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 作用于类 保留至运行时
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoadPro {
String className();
String methodName();
}
使用
package com.xhh.reflection;
import java.lang.reflect.Method;
@LoadPro(className = "com.xhh.reflection.Dog", methodName = "dogMethod")
public class LoadProTest {
public static void main(String[] args) throws Exception {
// 1 解析注解
// 1.1 获取当前类的字节码对象
Class<LoadProTest> lpcls = LoadProTest.class;
// 1.2 获取定义注解的对象
LoadPro anno = lpcls.getAnnotation(LoadPro.class);
// 1.3 通过注解对象的抽象方法,获取返回值
String className = anno.className();
String methodName = anno.methodName();
// 反射对象执行方法
Class<?> cls = Class.forName(className);
Object obj = cls.newInstance();
Method method = cls.getMethod(methodName);
method.invoke(obj);
}
}