`
longgangbai
  • 浏览: 7250917 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

RestFuse的研究(二) Junit的Runner的分类和模式

阅读更多

      在Junit4中的调用JunitCore可以采用两种方式命令行调用和编程式实现.无论那种方式最终都要调用

	public Result run(Computer computer, Class<?>[] classes) {
		return run(Request.classes(computer, classes));
	}

	public Result run(Request request) {
		return run(request.getRunner());
	}

	public Result run(Test test) {
		return run(new JUnit38ClassRunner(test));
	}

 

在Junit4中Request.classes的方法具体执行什么呢?可以看出是执行器Runner对象.

 

那么Junit有几种执行的方式呢?
可以说是四种:

1.Junit3方式Runner

2.junit4方式Runner

3.注解方式Runner

4.Ignore方式Runner

 

 

下面我们来分析一下源代码:

	public static Request classes(Computer computer, Class<?>[] classes) {
		try {
			AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(
					true);
			Runner suite = computer.getSuite(builder, classes);
			return runner(suite);
		} catch (InitializationError e) {
			throw new RuntimeException(
					"Bug in saff's brain: Suite constructor, called as above, should always complete");
		}
	}

 

有上面代码可以看出AllDefaultPossibilitiesBuilder 可能使用创建者模式对象具体干嘛呢?

源代码如下:

public class AllDefaultPossibilitiesBuilder extends RunnerBuilder {
	private final boolean fCanUseSuiteMethod;

	public AllDefaultPossibilitiesBuilder(boolean canUseSuiteMethod) {
		this.fCanUseSuiteMethod = canUseSuiteMethod;
	}

	public Runner runnerForClass(Class<?> testClass) throws Throwable {
		List builders = Arrays.asList(new RunnerBuilder[] { ignoredBuilder(),
				annotatedBuilder(), suiteMethodBuilder(), junit3Builder(),
				junit4Builder() });

		for (RunnerBuilder each : builders) {
			Runner runner = each.safeRunnerForClass(testClass);
			if (runner != null) {
				return runner;
			}
		}
		return null;
	}

	protected JUnit4Builder junit4Builder() {
		return new JUnit4Builder();
	}

	protected JUnit3Builder junit3Builder() {
		return new JUnit3Builder();
	}

	protected AnnotatedBuilder annotatedBuilder() {
		return new AnnotatedBuilder(this);
	}

	protected IgnoredBuilder ignoredBuilder() {
		return new IgnoredBuilder();
	}

	protected RunnerBuilder suiteMethodBuilder() {
		if (this.fCanUseSuiteMethod) {
			return new SuiteMethodBuilder();
		}
		return new NullBuilder();
	}
}

 AllDefaultPossibilitiesBuilder 继承RunnerBuider,用于创建各种Runner的实现.

首先看看JUnit4Builder怎么实现:

public class JUnit4Builder extends RunnerBuilder {
	public Runner runnerForClass(Class<?> testClass) throws Throwable {
		return new BlockJUnit4ClassRunner(testClass);
	}
}

 JUnit4Builder 构建主要使用BlockJUnit4ClassRunner运行的测试用例.

 

Junit3Builder可以猜测为Junit3实现的单元测试使用

源代码:

public class JUnit3Builder extends RunnerBuilder {
	public Runner runnerForClass(Class<?> testClass) throws Throwable {
		if (isPre4Test(testClass)) {
			return new JUnit38ClassRunner(testClass);
		}
		return null;
	}

	boolean isPre4Test(Class<?> testClass) {
		return TestCase.class.isAssignableFrom(testClass);
	}
}

  可以看出junit3主要执行的Runner主要为JUnit38ClassRunner对象.

 

 

AnnotatedBuilder对象是干嘛用呢?主要是为注解实现的Runner运行器对象.

public Runner runnerForClass(Class<?> testClass) throws Exception {
		RunWith annotation = (RunWith) testClass.getAnnotation(RunWith.class);
		if (annotation != null) {
			return buildRunner(annotation.value(), testClass);
		}
		return null;
	}

	public Runner buildRunner(Class<? extends Runner> runnerClass,
			Class<?> testClass) throws Exception {
		try {
			return ((Runner) runnerClass.getConstructor(
					new Class[] { Class.class }).newInstance(
					new Object[] { testClass }));
		} catch (NoSuchMethodException e) {
			try {
				return ((Runner) runnerClass.getConstructor(
						new Class[] { Class.class, RunnerBuilder.class })
						.newInstance(
								new Object[] { testClass, this.fSuiteBuilder }));
			} catch (NoSuchMethodException e2) {
				String simpleName = runnerClass.getSimpleName();
				throw new InitializationError(
						String.format(
								"Custom runner class %s should have a public constructor with signature %s(Class testClass)",
								new Object[] { simpleName, simpleName }));
			}
		}
	}

 可以看出AnnotatedBuilder主要是为使用RunWith且RunWith内的Class为Runner的对象实现执行的一种方式.还有一个就是IgnoredBuilder,这个是忽略执行的我们很少考虑这里就不再分析.

 

 

由此可见:

         HttpJUnitRunner是Junit4的一种实现.在执行单元测试的时候采用的注解的方式执行.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics