package gxy.test.Junit;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MyJUnit {
// 存放所有标注了before注解的集合
private List<Method> beforeMethod;
// 存放所有标注了after注解的集合
private List<Method> afterMethod;
// 存放所有标注了test注解的集合
private List<Method> testMethod;
// 存放需要捕捉的异常集合
private static List<Exception> exceptions;
// 被测试类的实例化对象
private Object object;
// 被测试类的Class对象
private Class<?> testClass;
//自定义MyJUnit类的构造方法,用于接收被测试类的名字然后初始化需要的变量和方法
public MyJUnit(String testName) {
super();
try {
beforeMethod = new ArrayList<>();
afterMethod = new ArrayList<>();
testMethod = new ArrayList<>();
exceptions = new ArrayList<>();
//使用反射根据传递的类名生成对象
testClass = Class.forName(testName);
object = testClass.newInstance();
//获取所有的方法并根据注解进行分类
getAllMethods();
} catch (Exception e) {
e.printStackTrace();
}
}
// 根据注解获取所有的方法
private void getAllMethods() {
Method[] methods = testClass.getMethods();
for (Method m : methods) {
// 找到被before修饰的方法,放入before方法的集合中
if (m.isAnnotationPresent(Before.class)) {
beforeMethod.add(m);
}
// 找到被After修饰的方法,放入after方法的集合中
if (m.isAnnotationPresent(After.class)) {
afterMethod.add(m);
}
// 找到被test修饰的方法,放入test方法的集合中
if (m.isAnnotationPresent(Test.class)) {
testMethod.add(m);
}
}
}
// run方法
public void run() {
// 运行所有的测试方法
for (Method method : testMethod) {
runTest(method);
}
// 判断捕捉的异常集合,如果大小为0则没有异常,测试通过。有异常则表示测试不通过并打印异常信息
if (exceptions.size() == 0) {
System.out.println("通过测试");
} else {
for (Exception e : exceptions) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("测试不通过,错误的内容为:");
e.printStackTrace();
}
}
}
// 按照before test after的顺序执行
private void runTest(Method method) {
try {
runBefores();
runTestMethod(method);
runAfters();
} catch (Exception e) {
e.getMessage();
throw new RuntimeException(
"test should never throw an exception to this level");
}
}
// 执行所有after标注的方法
private void runAfters() throws Exception {
for (Method m : afterMethod) {
m.invoke(object, new Object[] {});
}
}
// 执行所有before标注的方法
private void runBefores() throws Exception {
for (Method m : beforeMethod) {
m.invoke(object, new Object[] {});
}
}
// 执行test方法
private void runTestMethod(Method method) {
// 判断测试是否通过的标志
boolean passCheck = false;
try {
// 获得Test注解
Test testAnnotation = method.getAnnotation(Test.class);
// 判断test注解标注的属性是否为需要的类型,这里可以根据需要加入不同的判断条件
if (testAnnotation.expected().newInstance() instanceof Exception) {
passCheck = true;
}
method.invoke(object);
} catch (Exception e) {
// 判断通过则测试通过,否者将异常加入到异常集合中
if (passCheck) {
return;
} else {
addExceptions(e);
}
}
}
private static void addExceptions(Exception e) {
exceptions.add(e);
}
// 自定义的assertEquals方法,判断两个值是否相等,可以根据需要加入更多类型的判断,如果相等则通过,否则new一个异常加入到异常集合中
static public void assertEquals(Object expected, Object actual) {
if (expected.equals(actual)) {
return;
} else {
addExceptions(new Exception("预期值与实际值不相等"));
}
}
}