JUnit4.8.2源代码分析-2 org.junit.runner.Request和Description

JUnit4.8.2源代码中,最令yqj2065感兴趣的是org.junit.runner.Request,它是几个意思呢?

①封装JUnit的输入

JUnit4作为信息处理单元,它的输入是单元测试类——布满各种JUnit4的RUNTIME标注的类,但由于使用反射机制,JUnit4的输入严格地说是一个或多个(组)单元测试类的Class对象。早期版本的JUnit主要处理一个测试或测试构成的树,在增添了对过滤/
filtering和排序/ sorting支持后,JUnit4加入了这个概念。毕竟按照1.2.4 Java Annotation 提要的直接使用反射机制方式,代码会很复杂。

②知子莫若父??

面向对象中,一般父类不知其子类。然而在这里我们看见了反例。BlueJ中生成的JavaDoc

父类何时应该知道子类?这是一个问题,我只记得在WCF中遇到过数据契约中有个KnownType的东西。Request源代码中import其各个子类,并在一系列静态方法中使用它们而返回Request对象。Request是一个抽象类,通过静态方法返回Request(的子类) 的对象,这到底得和new有多大的仇恨啊。不过我喜欢。这些静态方法我不称其为静态工厂

public static Request aClass(Class<?> clazz)

public static Request classWithoutSuiteMethod(Class<?> clazz)

public static Request classes(Computer computer, Class<?>... classes)

public static Request classes(Class<?>...classes)

public static Request runner(final Runner runner)

public static Request method(Class<?> clazz, String methodName) {

Description method= Description.createTestDescription(clazz,methodName);

return Request.aClass(clazz).filterWith(method);

}

Request.method()将一个@Test封装为Request,毕竟@Test是基础。【HelloWorld 的单元测试类TestInJUnit4见源代码分析-1

例程 8-3测试Request类
package myTest;
import org.junit.runner.*;
public class RequestDemo{
    public static void test()throws Exception{
        Request rqst = Request.method(TestInJUnit4.class,"add");
        Result r = new JUnitCore().run(rqst);
        System.out.println(r.wasSuccessful() );
    }
}

③Request运用了工厂方法模式。

Request有一个工厂方法:public abstractRunner getRunner();

而且Request的设计有一个奇妙的地方:在创建对象的时候似乎使用装饰模式?Request为装饰模式中的Component、org.junit.internal.request.ClassRequest为具体组件,而FilterRequest和SortingRequest为具体装饰者(没有抽象Decorator)。而这一切,目的却是为了构建Request相关的Runner。

④Request使用set串接模式

Request的其他非静态方法filterWith、sortWith可以视为set方法。Request.method()中给出了例子:

return Request.aClass(clazz).filterWith(method);

Description

一个Request就搞得我昏头转向的,还是Description简单,它封装将要测试或已经测试的测试信息。使用组合模式,所有元素都是Composite对象。

有两个命名常量EMPTY(名字为"No Tests")和TEST_MECHANISM(名字为"Test mechanism")

作为叶子时,包含的atomic(a single test)信息有:

privatefinal String fDisplayName;// 本描述的显示名字(toString()的返回值)

privatefinal Annotation[] fAnnotations;// 一个测试的所有Annotation[]

相关的get方法:Collection<Annotation>getAnnotations()、StringgetDisplayName()、DescriptionchildlessCopy()、StringgetClassName()、StringgetMethodName()。

作为Composite时,维护一个ArrayList<Description>,有相关的方法:addChild(Description)、ArrayList<Description>getChildren()、isTest()(是否叶子)、isSuite()(是否组合)、isEmpty()。

Description的操作:int testCount()包含的叶子测试的总数。

Description有一个私有构造器,而提供了静态方法获得Description对象。

本文涉及的类型:Request及其3个子类,Description;涉及的设计模式:工厂方法模式、set串接模式、装饰模式、组合模式

相关的类型:Runner、AllDefaultPossibilitiesBuilder、Filter等。

时间: 2024-08-25 19:11:41

JUnit4.8.2源代码分析-2 org.junit.runner.Request和Description的相关文章

JUnit4.8.2来源分析-2 org.junit.runner.Request

JUnit4.8.2源代码,最为yqj2065兴趣是org.junit.runner.Request,现在是几点意味着它? ①封装JUnit的输入 JUnit4作为信息处理单元,它的输入是单元測试类--布满各种JUnit4的RUNTIME标注的类,但因为使用反射机制,JUnit4的输入严格地说是一个或多个(组)单元測试类的Class对象.早期版本号的JUnit主要处理一个測试或測试构成的树,在增添了对过滤/ filtering和排序/ sorting支持后,JUnit4增加了这个概念.毕竟依照1

JUnit4.8.2源代码分析-1说明

由于yqj2065下载使用的BlueJ集成的是JUnit4.8.2,所以就分析一下JUnit4.8.2的源代码. JUnit是由GOF 之一的Erich Gamma 和 Kent Beck 编写的一个开源的单元测试框架,分析JUnit源代码的主要目的是学习其中对设计模式的运用.JUnit也是一个研究如何应对版本升级和接口变化的案例. 阅读源代码,首先需要知道该框架的设计需求.如果使用过JUnit,单元测试的需求应该比较熟悉.从简单的例子入手,有应用程序(待测试的类)HelloWorld,为了使用

JUnit4.8.2源代码分析-4 RunNotifier与RunListener

JUnit4执行过程中,org.junit.runner.notification. RunListener和RunNotifier运用了观察者模式. 1.观察者 观察者Observer/Listener主要作用是分析各种事件并定义相应的回调接口.例如JDK中MouseListener处理鼠标键相关的5个动作:鼠标键被按下/pressed.释放/released.单击/clicked.光标进入或离开某组件/enters or exits.java.awt.event .MouseListener

JUnit4.8.2源代码分析-3 TestClass 和RunnerBuilder

吃柿子专挑软的捏.JUnit4的核心是org.junit.runner.Runner,它涉及的类型太多,今天看几个简单的类型.看完了而且不准备回头再看的类型,yqj2065会在BlueJ中将它删除.删除如NullBuilder时,将import org.junit.internal.builders.NullBuilder加到本包的它的客户类中(其他包使用的,是BlueJ库中引入的包文件中的类),以保证整个项目可以编译和生成JavaDoc. org.junit.runners.model.Tes

JUnit4.8.2源代码分析-3.2 Computer

本系列文章,记录yqj2065阅读JUnit源代码的过程,很多时候在阅读过程中有许多不理解的地方,例如某某类是干什么的,为什么需要它,为什么不这样设计--等等. org.junit.runner是JUnit最核心的包,其中的Computer/计算机(是这样翻译么),它是个什么意思呢?刚开始读JUnitCore的时候,我就很不明白. package org.junit.runner; import org.junit.runners.Suite; import org.junit.runners.

JUnit4.8.2源代码分析-3.1 Description-测试树

重新把org.junit.runner.Description的源代码读了一下,结合成组测试(Suite)了解Description所表示的测试树. Description使用组合模式描述一个测试的信息.所有元素都是Composite对象. 例如myTest.units包中有Unit1.Unit2.Unit3,而SuiteUnit将Unit2.Unit3和myTest.param.ParametTestUnit组成一组.     public static void tree(){      

JUnit4.8.2源代码分析-6.1 排序和过滤

Runner.sort.Request.sortWith和Sorter.apply yqj2065都快被它们搞死了. Sorter.apply().Request.sortWith()和Sortable.sort()三者做一件事情?为什么呢? java.util.Comparator接口是一个策略类,定义了int compare(T o1, T o2)方法.org.junit.runner.manipulation.Sorter implements Comparator<Description

junit4.12源码分析-启动到选择runner

第一次写源代码分析,介绍运行流程和其中重要的类和接口! JUnitCore JUnitCore采用门面模式,可以启动junit4,junit3测试,也可以测试指定class.JUnitCore声明RunNotifier类,该类采用观察者模式实现事件管理.RunListener为测试事件基类,有测试开始结束失败等事件,如果想自定义事件可以继承该类.默认增加了两个RunListener,一个是TextListener,另一个是Result类函数createListener构造的Listener用于记

JUnit4.8.2源代码分析-5 Statement

org.junit.runners.model.Statement/语句是对运行JUnit测试组过程中的一个或多个动作的封装.如果说Runner.run()表示运行JUnit测试组的整个过程,则Statement表示其中或大或小的步骤.针对方法的标注如@Test .@Before.@After.@BeforeClass.@AfterClass具有某些执行的顺序,Statement是整个过程的一个步骤结点,而诸多Statement构成的链式结构表达了整个过程.在各种Runner中广泛使用它们. o