JUnit 定义了 Request 契约接口 (其实是一个抽象类), 便于其他的装置(比如 maven, eclipse 等 ide 工具) 触发 Junit 执行, 这个接口的定义如下:
- public abstract class Request {
- public static Request aClass(Class < ?>clazz) {
- return new ClassRequest(clazz);
- }
- public abstract Runner getRunner();
- }
一堆根据 Class 创建 Request 实例的的静态方法, 以及 getRunner()方法, getRunner()的默认实现为根据 @RunWith 注解选择合适的 Runner(BlockJUnit4ClassRunner, Suite, SpringJUnit4ClassRunner)等,
Runner 主要的方法如下
- public abstract class Runner implements Describable {
- public Runner(Class < ?>clazz);
- public abstract void run(RunNotifier notifier);
- }
在构造函数中完成初始化, BlockJUnit4ClassRunner 的实现是通过反射查找传入的类中(@Test, @Before 等注解的方法),
run()表示开始执行该类中定义的 Test case
Junit 将执行 @Test 注解的方法的每一步抽象为一个 Statement 对象, 类似 servlet 的 filter
- public abstract class Statement {
- private final Statement next;
- public abstract void evaluate() throws Throwable;
- }
next 指针定义在子类中的(便于叙述仿真 Statement 中), 因为有些 Statement 不需要下一步动作, 比如 Fail 对象
假设有如下测试对象,
- public class JunitTest {
- @BeforeClass
- public static void beforeClass() {}
- @Before
- public void before() {}
- @Test
- public void test() {}
- }
那么 Statement 的链式结构如下
BeforeStatement {
..... 处理 @BeforeClass 注解的方法
- next = AllTestAnnotationedMethodStatement {
- for (FrameworkMethod...) {
- // 参考 BlockJUnit4ClassRunner.methodBlock 中构建过程
- withBeforesStatement {
..... 处理 @Before 注解的方法
next = methodInvokerStatement {
..... 处理 @Test 注解的方法
- }
- }
- }
- }
- }
Posted in: java 基础
来源: http://www.javacoder.cn/?p=1228