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