JUnit4源碼解讀
其中
直接看代碼
//BlockJUnit4ClassRunner.class
protected Statement methodBlock(final FrameworkMethod method) {
Object test;
try {
test = (new ReflectiveCallable() {
protected Object runReflectiveCall() throws Throwable {
return BlockJUnit4ClassRunner.this.createTest(method);
}
}).run();
} catch (Throwable var4) {
return new Fail(var4);
}
Statement statement = this.methodInvoker(method, test);
statement = this.possiblyExpectingExceptions(method, test, statement);
statement = this.withPotentialTimeout(method, test, statement);
statement = this.withBefores(method, test, statement);
statement = this.withAfters(method, test, statement);
statement = this.withRules(method, test, statement);
statement = this.withInterruptIsolation(statement);
return statement;
}
//調用
protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
Description description = this.describeChild(method);
if (this.isIgnored(method)) {
notifier.fireTestIgnored(description);
} else {
Statement statement = new Statement() {
public void evaluate() throws Throwable {
BlockJUnit4ClassRunner.this.methodBlock(method).evaluate();
}
};
this.runLeaf(statement, description, notifier);
}
}
為什麼就可以鍊式觸發呢 其實看源碼中的
protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) {
List<FrameworkMethod> afters = this.getTestClass().getAnnotatedMethods(After.class);
return (Statement)(afters.isEmpty() ? statement : new RunAfters(statement, afters, target));
}
public RunAfters(Statement next, List<FrameworkMethod> afters, Object target) {
this.next = next;
this.afters = afters;
this.target = target;
}
是因為在next儲存了statement,并且在自己的evaluate中寫入了next.evaluate,這樣就可以一層一層調用了各個evaluate了。