• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • JUnit源碼解析(3)

    發表于:2016-10-04來源:saymagic作者:saymagic點擊數: 標簽:junit
    } }); } } finally { currentScheduler.finished(); } } 這個函數就體現了抽象的重要性,注意泛型T,它在ParentRunner的每個實現類中各不相同,在BlockJUnit4ClassRunner中T表示
                        }
                   });
             }
         } finally {
             currentScheduler.finished();
         }
    }
    這個函數就體現了抽象的重要性,注意泛型T,它在ParentRunner的每個實現類中各不相同,在BlockJUnit4ClassRunner中T表示FrameworkMethod,具體到這個函數來講getFilteredChildren拿到的是被@Test注解標注的FrameworkMethod,而在Suite中,T為Runner,而ParentRunner.this.runChild(each, notifier);這句的中的runChild(each, notifier)方法依舊是個抽象方法,我們先看BlockJUnit4ClassRunner中的實現:
     
    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
         Description description = describeChild(method);
         if (isIgnored(method)) {
             notifier.fireTestIgnored(description);
         } else {
             runLeaf(methodBlock(method), description, notifier);
         }
    }
    isIgnored方法判斷了method方法是否被@Ignore注解標識,如果是的話則直接通知notifier觸發ignored事件,否則,執行runLeaf方法, runLeaf的第一個參數是Statement,所以,BlockJUnit4ClassRunner通過methodBlock方法將method轉換為Statement:
     
    protected Statement methodBlock(FrameworkMethod method) {
            Object test;
            try {
                test = new ReflectiveCallable() {
                    @Override
                    protected Object runReflectiveCall() throws Throwable {
                        return createTest();
                    }
                }.run();
            } catch (Throwable e) {
                return new Fail(e);
            }
            Statement statement = methodInvoker(method, test);
            statement = possiblyExpectingExceptions(method, test, statement);
            statement = withPotentialTimeout(method, test, statement);
            statement = withBefores(method, test, statement);
            statement = withAfters(method, test, statement);
            statement = withRules(method, test, statement);
            return statement;
     }
    前面的幾行代碼是在生成test 對象,而test對象的類型則是我們待測試的class,接下來追進methodInvoker方法:
     
    protected Statement methodInvoker(FrameworkMethod method, Object test) {
            return new InvokeMethod(method, test);
    }
    可見,我們生成的Statement實例為InvokeMethod,我們看下其evaluate方法:
     
    testMethod.invokeExplosively(target);
    invokeExplosively函數做的事情就是對target對象調用testMethod方法。而前面我們說過,這個testMethod在BlockJUnit4ClassRunner中就是被@Test所標注的方法,此時,我們終于找到了@Test方法是在哪里被調用的了。別急,我們接著剛才的函數繼續分析:
     
    statement = possiblyExpectingExceptions(method, test, statement);
    statement = withPotentialTimeout(method, test, statement);
    statement = withBefores(method, test, statement);
    statement = withAfters(method, test, statement);
    statement = withRules(method, test, statement);
    我們可以看到,statement不斷的在變形,而通過withBefores,withRules這些函數的名字我們可以很容易猜到,這里就是在處理@Before,@Rule等注解的地方,我們以withBefores為例:
     
    protected Statement withBefores(FrameworkMethod method, Object target,
                Statement statement) {
            List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods(
                    Before.class);

    原文轉自:http://blog.saymagic.cn/2016/09/30/understand-Junit.html

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>