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的一种实现.在执行单元测试的时候采用的注解的方式执行.