Junit 源码解析(二)

这里对BlockJUnit4ClassRunner中几个跟写单元测试最相关的几个方法进行分析

(1)构造方法
	public BlockJUnit4ClassRunner(Class<?> klass) throws InitializationError {
		super(klass);
	}
作用:是取得类的声名描述,即Class<?> klass

(2)createTest
protected Object createTest() throws Exception {
		return getTestClass().getOnlyConstructor().newInstance();
	}
作用:根据Class,创建测试用例类实例。
(3)withPotentialTimeout
	protected Statement withPotentialTimeout(FrameworkMethod method,
			Object test, Statement next) {
		long timeout= getTimeout(method.getAnnotation(Test.class));
		return timeout > 0 ? new FailOnTimeout(next, timeout) : next;
	}
(4)withBefores
	protected Statement withBefores(FrameworkMethod method, Object target,
			Statement statement) {
		List<FrameworkMethod> befores= getTestClass().getAnnotatedMethods(
				Before.class);
		return new RunBefores(statement, befores, target);
	}
     我们在单元测试时加注解@Befores,就是调用这个方法被执行的。

(5) withAfters
	protected Statement withAfters(FrameworkMethod method, Object target,
			Statement statement) {
		List<FrameworkMethod> afters= getTestClass().getAnnotatedMethods(
				After.class);
		return new RunAfters(statement, afters, target);
	}
我们在单元测试时加注解@Afters,就是调用这个方法被执行的。
(6) 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);
		}

		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);
		return statement;
	}


(6) 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);
		}

		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);
		return statement;
	}
分析这个类的原因,是想了解Junit的方法执行顺序是如何处理的。
采用的是双向链表的数据结构。而Statement代表了一个操作,即单元测试中所要处理的一个环境。像在单元测试中所加的注解@Befores,@Afters等等都是Statement。Statement是个抽象类,所以操作都要重写evaluate方法,在继承statement的同时,做成双向的有序链表,这样就可以顺序的执行操作了。以RunBeforeTestMethod的源代码可以看到这点。

public class RunBeforeTestMethod extends Statement {

	private final Statement next;

	private final Object testInstance;

	private final Method testMethod;

	private final TestContextManager testContextManager;

	public RunBeforeTestMethod(Statement next, Object testInstance, Method testMethod,
			TestContextManager testContextManager) {
		this.next = next;
		this.testInstance = testInstance;
		this.testMethod = testMethod;
		this.testContextManager = testContextManager;
	}

	@Override
	public void evaluate() throws Throwable {
		this.testContextManager.beforeTestMethod(this.testInstance, this.testMethod);
		this.next.evaluate();
	}

}
而前面提到的代码
		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);
就是在整理各个操作间执行的先后顺序。


以上简单分析了Junit是如何执行单元测试用例的。
下一节介绍如何扩做自己的容器。以Spring提供实现为例。

你可能感兴趣的:(java,spring,数据结构,JUnit,单元测试)