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(