我们通常在一个class里面定义一些方法,这些方法最终被执行是通过函数
org.junit.runners.BlockJUnit4ClassRunner.runChild 被触发。
源码如下:
@Override protected void runChild(final FrameworkMethod method, RunNotifier notifier) { //获得描述 Description description = describeChild(method); //是否需要被忽略,如果被忽略就触发fireTestIgnored函数 if (isIgnored(method)) { notifier.fireTestIgnored(description); } else { //正常情况下,都要走到本行 runLeaf(methodBlock(method), description, notifier); } }
然后,进入methodBlock函数
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); }
证明如下:
Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner$1.(), line=263 bci=9263 test = new ReflectiveCallable() {main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodBlock(), line=268 bci=8268 }.run();main[1] step> Step completed: "thread=main", org.junit.internal.runners.model.ReflectiveCallable.run(), line=12 bci=012 return runReflectiveCall();main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(), line=266 bci=0266 return createTest();main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.createTest(), line=217 bci=0217 return getTestClass().getOnlyConstructor().newInstance();
看看getOnlyConstructor是个什么鬼!
Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.createTest(), line=217 bci=4217 return getTestClass().getOnlyConstructor().newInstance();main[1] step> Step completed: "thread=main", org.junit.runners.model.TestClass.getOnlyConstructor(), line=203 bci=0203 Constructor [] constructors = clazz.getConstructors();main[1] next> Step completed: "thread=main", org.junit.runners.model.TestClass.getOnlyConstructor(), line=204 bci=8204 Assert.assertEquals(1, constructors.length);main[1] next> Step completed: "thread=main", org.junit.runners.model.TestClass.getOnlyConstructor(), line=205 bci=15205 return constructors[0];
也就是说,只容许有1个构造函数!
我看了下我的测试类,没有显示提供构造函数,JVM默认提供了一个默认构造函数!
---继续debug生成实例
Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.createTest(), line=217 bci=7217 return getTestClass().getOnlyConstructor().newInstance();main[1] print getTestClass().getOnlyConstructor() getTestClass().getOnlyConstructor() = "public mytest.CalculatorTest()"main[1] step> Step completed: "thread=main", mytest.CalculatorTest.(), line=7 bci=17 public class CalculatorTest {main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.createTest(), line=217 bci=14217 return getTestClass().getOnlyConstructor().newInstance();
到这里,一个测试类的实例就生成了!
Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodBlock(), line=263 bci=11263 test = new ReflectiveCallable() {main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodBlock(), line=269 bci=12269 } catch (Throwable e) {main[1] print test test = "mytest.CalculatorTest@66d33a"
继续debug,接下来会执行下面的一些代码
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;
先看第一行
Statement statement = methodInvoker(method, test);
debug结果为
Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodBlock(), line=273 bci=25273 Statement statement = methodInvoker(method, test);main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodInvoker(), line=290 bci=0290 return new InvokeMethod(method, test);main[1] print method method = "public void mytest.CalculatorTest.evaluatesExpression()"main[1] print test test = "mytest.CalculatorTest@66d33a"main[1] step> Step completed: "thread=main", org.junit.internal.runners.statements.InvokeMethod.(), line=10 bci=010 public InvokeMethod(FrameworkMethod testMethod, Object target) {main[1] step> Step completed: "thread=main", org.junit.runners.model.Statement. (), line=10 bci=010 public abstract class Statement {main[1] step> Step completed: "thread=main", org.junit.internal.runners.statements.InvokeMethod. (), line=11 bci=411 this.testMethod = testMethod;main[1] step> Step completed: "thread=main", org.junit.internal.runners.statements.InvokeMethod. (), line=12 bci=912 this.target = target;main[1] step> Step completed: "thread=main", org.junit.internal.runners.statements.InvokeMethod. (), line=13 bci=1413 }main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodInvoker(), line=290 bci=9290 return new InvokeMethod(method, test);main[1] step> Step completed: "thread=main", org.junit.runners.BlockJUnit4ClassRunner.methodBlock(), line=273 bci=31273 Statement statement = methodInvoker(method, test);
很显然,这个statement对象标识了执行一个类的某个方法
继续看第2行,
statement = possiblyExpectingExceptions(method, test, statement);
statement = withPotentialTimeout(method, test, statement);这个主要是跟异常捕捉和执行超时有关,暂时忽略。
下面还有3行,代码如下:
statement = withBefores(method, test, statement); statement = withAfters(method, test, statement); statement = withRules(method, test, statement);
这个主要是确定方法的执行顺序,我们以第一个withBefores为例
执行时候,触发下面的代码
public RunBefores(Statement next, Listbefores, Object target) { this.next = next; this.befores = befores; this.target = target; } @Override public void evaluate() throws Throwable { for (FrameworkMethod before : befores) { before.invokeExplosively(target); } next.evaluate(); }
这个就不用解释了吧。
---
那么,这里就可以顺利执行完一个测试流程。