自定义@MyTest注解实现单元测试
目的: 完成自定义注解@MyTest,并实现标有注解的方法并启动它。(模拟@Test注解做单元测试)
步骤:
新建一个注解类(annotation),命名为MyTest
创建一个TestJunit单元测试类,写几个方法,比如:public void test1()
创建一个MyTestDemo测试类(主功能实现类),该类主要利用反射机制来实现对TestJunit单元测试类中加@MyTest注解方法的启动
给予注解类生命周期与反射机制吻合,也就是定义的注解可以保留到运行时,通过反射机制可以获取注解信息
编写MyTestDemo测试类,利用反射获取TestJunit单元测试类的Class对象,并获取单元测试类中所有的方法对象,遍历所有方法对象,只要加@MyTest的注解的方法把他执行起来,不加注解的不给予任何处理操作
启动测试类,查看结果(执行结果,在最后面!)
注意:
自定义注解类中,没有编写注解体,也就是没有给默认value值。因为该注解只是起到了标识的作用,标识需要启动的方法
注解类编译后也是.class文件
通过反射机制来完成自定义注解操作,一定要给与注解和反射同样的生命周期
你要知道我们是不能完成Junit4、Junit5这样类型的插件功能的,可以选择性的执行加了注解的方法,而且我们有实力写出插件IDEA也是不承认的。不会给你生成run方法启动项
MyTest注解类
package com.mylifes1110.java.anno;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
- 此自定义注解@MyTest只是作为需要单元测试的标记,不需要做默认值
- @Retention注解表示给与@MyTest注解生命周期
- 当前定义的注解可以保留到运行时,通过反射机制可以获取注解信息
- 否则反射将对注解没有任何作用,失去了该意义和自定义单元测试的初衷
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
// String value() default “”;
}
TestJunit单元测试类
package com.mylifes1110.java.test.junit;
import com.mylifes1110.java.anno.MyTest;
import org.junit.Test;
public class TestJunit {
@Test
public void test1() {
System.out.println("---test1---");
}
@MyTest
public void test2() {
System.out.println("---test2---");
}
@MyTest
public void test3() {
System.out.println("---test3---");
}
public void test4() {
System.out.println("---test4---");
}
}
MyTestDemo测试类(主要实现功能并测试)
package com.mylifes1110.java.test.junit;
import com.mylifes1110.java.anno.MyTest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
-
让自定义的MyTest注解起作用
-
通过反射,扫描TestJunit类中有哪些方法上方加了MyTest注解
-
如果加@MyTest注解的则执行它
-
如果没有加@MyTest注解的则不做任何处理
/
public class MyTestDemo {
public static void main(String[] args) {
/*
* 1.获取TestJunit类对应的Class对象
/
Class junitClass = TestJunit.class;
/*
* 获取TestJunit类中所有的方法对象
*/
Method[] methods = junitClass.getMethods();/** * 遍历所有方法对象查找有与没有@MyTest注解,并做出响应处理 */ for (Method method : methods) { boolean present = method.isAnnotationPresent(MyTest.class); /** * TestJunit类中有@MyTest注解的执行该方法 */ if (present) { try { method.invoke(junitClass.newInstance()); } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { e.printStackTrace(); } } else { /** * TestJunit类中没有@MyTest注解的不做任何操作 * 此else分支冗余,只是为了做标记,让你们好理解 */ } }
}
}