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了。