標籤:註解 自訂註解 annotation 註解實現junit
前面兩次的自訂註解,都只是解析了一個註解,今天要講的junit需要三個註解,而且解析架構中反射啟用方法時要根據Before、Test、After的順序來執行,需要注意的是Test註解可能會有多個,所以我們在外面定義一個數組,用來儲存所有由@Test標註的方法。下面來看一下具體實現
- 三個註解的定義
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface Before {}
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface Test {}
@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface After {}
- 在自己的測試類別中使用自訂好的三個註解
public class MyJunitTest { @Before public void prepare(){ System.out.println(" before :所有的測試方法之前都先執行這個方法"); } @After public void destroy(){ System.out.println(" destroy :所有的測試方法之後都要執行這個方法"); } @Test public void testAdd(){ System.out.println(" test :testadd() "); } @Test public void testUpdate(){ System.out.println(" test :testUpdate() "); }}
- 最重要的註解解析架構
public class ParseJunit { public void parseMethod(Class clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { Object obj = clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); //Before 的註解只有一個,直接在外面定義一個Method類型的變數 Method methodsBefore=null; Method[] methodsTest=null; int index=0; Method methodsAfter=null; //迴圈所有的方法 for (Method m : methods) { //得到方法上的所有註解,因為不確定是Before還是After、Test,不能直接根據class得到註解 Annotation[] myJunitTest =m.getAnnotations(); //迴圈所有的註解,根據名字匹配 for(int i=0;i<myJunitTest.length;i++){ //根據名字匹配註解的類型 if(myJunitTest[0].annotationType().getSimpleName().endsWith("Before")){ methodsBefore=m; }else if(myJunitTest[0].annotationType().getSimpleName().endsWith("Test")){ //如果為 Test ,判斷這個數組是否為空白,否:存入定義好的 數組中 然後下標加一 if(methodsTest==null){ //是,新產生一個數組,然後將 m 存入 methodsTest=new Method[ methods.length ]; } methodsTest[index]=m; index++; }else if(myJunitTest[0].annotationType().getSimpleName().endsWith("After")){ methodsAfter=m; } } } //1、先執行 Before註解的方法 if(methodsBefore!=null){ methodsBefore.invoke(obj); } //2、執行Test 註解的 數組中的方法 if(methodsTest!=null && methodsTest.length>0){ for(Method m: methodsTest){ if(m!=null){ m.invoke(obj); } } } //3、最後執行 After 註解的方法 if(methodsAfter!=null){ methodsAfter.invoke(obj); } }}
可能運行效率不是最好的,但是基本效果已經實現,小夥伴們有更好的解決辦法,敬請指教啊
4. 下面我們測試一下自訂好的Junit
public void testApp() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { ParseJunit pj=new ParseJunit(); pj.parseMethod(MyJunitTest.class); }
結果:
自訂註解,最核心的部分就是解析架構的實現,上面提到的三個案例都是基於方法的註解,有興趣的小夥伴可以找找類註解、屬性註解的解析。
著作權聲明:本文為博主原創文章,謝謝參考!有問題的地方,歡迎糾正,一起進步。
自訂java註解(三) 實現Junit中的@Test、@Before、@After