【JUnit4.10源码分析】5.2 Rule
标注@Rule
TestRule是一个工厂方法模式中的Creator角色——声明工厂方法。
package org.junit.rules;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public interface TestRule {
Statement apply(Statement base, Description description);
}
因为工厂方法apply有參数base。因而TestRule将创建装饰模式中的装饰对象。
【抽象类Statement声明操作evaluate()的接口。它作为一个回调接口,上层模块能够定义各种Statement的子类。提供evaluate()的方法体。而这一主要的技术与Rule结合,成为JUnit一个很重要的手段——能够说它是一个通用型的复合命令的构造方式。全然能够代替Statement的一些复合命令的子类如ExpectException等。
】
測试程序猿要使用Rule,必须编写代码。以下先介绍使用Rule的样例。
1.MyStatement——Statement的一个新的装饰对象。( JUnit之Rule的使用中的样例),地位等同于ExpectException。
package rule;
import static tool.Print.*;//pln(Object)
import org.junit.runners.model.Statement;
/**
*
* @author yqj2065
*/
public class MyStatement extends Statement {
private final Statement base;
public MyStatement( Statement base ) {
this.base = base;
} @Override public void evaluate() throws Throwable {
pln( "before...sth..sth" );
try {
base.evaluate();
} finally {
pln( "after...sth..sth" );
}
}
}
2.一个详细的工厂。也就是定义工厂方法的TestRule的子类。MyRule将创建一个Statement的新的装饰对象MyStatement。如同工厂方法模式的一般使用方法,详细工厂与详细产品一一相应。
package rule;
import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;
public class MyRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
return new MyStatement( base );
}
}
3.使用新的装饰对象
用户类BlockJUnit4ClassRunner使用的是ExpectException等JUnit内建的Statement装饰对象;測试程序猿编写的Statement装饰对象,则须要通过@Rule,嵌入到单元測试类中。
package rule;
import org.junit.Rule;
import org.junit.Test;
public class MyTest {
@Rule
public MyRule myRule = new MyRule(); @Test()
public void xx() {
System.out.println( "xx()..." );
}
}
在开发环境中执行MyTest,输出:
before...sth..sth
xx()...
after...sth..sth
例程 8 17标注Rule
package org.junit;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Rule {}
注意:JUnit4.8中Rule标注并没有指定@Target(ElementType.FIELD),而4.10版本号中明白定义出来。Rule用于修饰測试单元类中一个特殊的域。该域必须是public、非static并且是org.junit.rules.TestRule子类型的引用变量(代替4.8版本号的org.junit.rules.MethodRule)。JUnit4.10版本号中还有一个标注@ClassRule,用于修饰測试单元类中static的TestRule子类型的引用变量。
TestRule
然而,装饰对象仍然是一个Statement。
TestRule的各种实现类创建很多装饰对象。可是没有特别的名字。反正是一个Statement。
从JUnit框架设计的角度看,TestRule是工厂方法;而从測试程序猿思考问题的角度,TestRule及事实上现类,为单元測试制订了各种附加的规则/Rule。
在org.junit.rules包中的TestRule的实现类有:
1. TestWatcher
对base加以监控的Rule。它不会对结果进行改动。
TestWatcher以匿名类的方式创建Statement装饰对象。在@Override evaluate()时使用了模板方法模式。
例程 8-4 TestWatchman
package org.junit.rules; import org.junit.internal.AssumptionViolatedException;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public abstract class TestWatcher implements TestRule {
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
starting(description);
try {
base.evaluate();
succeeded(description);
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable t) {
failed(t, description);
throw t;
} finally {
finished(description);
}
}
};
}
protected void succeeded(Description description) { }
protected void failed(Throwable e, Description description) { }
protected void starting(Description description) { }
protected void finished(Description description) { }
}
TestWatcher的子类TestName是模板方法模式中的详细类角色。
publicvoid starting(FrameworkMethod method) {
fName=method.getName();
}
2. Verifier
使用了模板方法模式,以匿名类的方式创建Statement装饰对象,在base. evaluate()之后加入一个verify()操作。Verifier的子类ErrorCollector收集測试中的错误。
3. ExpectedException和Timeout
ExpectedException作为工厂创建装饰对象,其私有内部类ExpectedExceptionStatement全然等价于org.junit.internal.runners.statements.ExpectException的地位。可是,ExpectedException作为规则将作用于各种測试方法。而ExpectException作用于@Test(expected=xxx)修饰的方法。
Timeout则是典型的工厂。返回一个装饰对象FailOnTimeout。
package org.junit.rules;
import org.junit.internal.runners.statements.FailOnTimeout;
import org.junit.runner.Description;
import org.junit.runners.model.Statement; public class Timeout implements TestRule {
private final int fMillis; /**
* @param millis the millisecond timeout
*/
public Timeout(int millis) {
fMillis= millis;
} public Statement apply(Statement base, Description description) {
return new FailOnTimeout(base, fMillis);
}
}
4. ExternalResource
ExternalResource使用了模板方法模式。以匿名类的方式创建Statement装饰对象。在base. evaluate()之前before()中能够加入各种其它资源(file, socket, server, database connection),而after()中释放资源。其子类TemporaryFolder给出了一个样例。
【JUnit4.10源码分析】5.2 Rule的更多相关文章
- 【JUnit4.10源码分析】5 Statement
假设要评选JUnit中最最重要的类型.或者说核心,无疑是org.junit.runners.model.Statement.Runner等类型看起来热闹而已. package org.junit.ru ...
- 【JUnit4.10源码分析】6.1 排序和过滤
abstract class ParentRunner<T> extends Runner implements Filterable,Sortable 本节介绍排序和过滤. (尽管JUn ...
- 【JUnit4.10源码分析】3.4 Description与測试树
Description使用组合模式描写叙述一个測试树.组合模式中全部元素都是Composite对象. Description有成员变量private final ArrayList<Descri ...
- JUnit源码分析 - 扩展 - 自定义Rule
JUnit Rule简述 Rule是JUnit 4.7之后新加入的特性,有点类似于拦截器,可以在测试类或测试方法执行前后添加额外的处理,本质上是对@BeforeClass, @AfterClass, ...
- JUnit4.12 源码分析之TestClass
1. TestClass // 源码:org.junit.runners.model.TestClass // 该方法主要提供方法校验和注解搜索 public class TestClass impl ...
- 10.源码分析---SOFARPC内置链路追踪SOFATRACER是怎么做的?
SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...
- JUnit4.12 源码分析之Statement
1. Statement 抽象类Statement作为命令模式的Command,只有一个方法 各种Runner作为命令模式中的Invoker,将发出各种Statement,来表示它们运行JUnit测试 ...
- JUnit4.12 源码分析(二)之TestRule
1. TestRule TestRule和@Before,@After,@BeforeClass,@AfterClass功能类似,但是更加强大; JUnit 识别TestRule的两种方式: 方法级别 ...
- 11.源码分析---SOFARPC数据透传是实现的?
先把栗子放上,让大家方便测试用: Service端 public static void main(String[] args) { ServerConfig serverConfig = new S ...
随机推荐
- 使用grep进行文本查找
命令模式: grep "文本" -rl 路径 例子: grep "w3.the.abc.com" -rl /home/hy/fluent3 有时候需要排除掉一些 ...
- 如何使用Total Recorder录制网上的音乐,如何下载只能试听的歌曲
1 在网上找到了对应的网站.其中正在播放的歌曲正是我们想要的 2 在地址栏输入上面音乐网站的网址,并点击捕获广播.(URL直接给出了音乐的完整地址,比如http://www.someserver.co ...
- Silverlight 之 断点调试
silverlight程序经常会遇到无法调试的情况,下面来总结解决方案. 一.问题描述 在Silverlight开发过程中,经常时不时的会碰到Silverlight无法调试的问题.如下几种情况: 1. ...
- PHP高级教程-过滤器
PHP 过滤器 PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入. 什么是 PHP 过滤器? PHP 过滤器用于验证和过滤来自非安全来源的数据. 测试.验证和过滤用户输入或自定义数据是 ...
- php之快速入门学习-11(数组排序)
PHP 数组排序 数组中的元素可以按字母或数字顺序进行降序或升序排列. PHP - 数组排序函数 在本章中,我们将一一介绍下列 PHP 数组排序函数: sort() - 对数组进行升序排列 rsort ...
- 二叉查找树实现实例(C语言)
/* search_tree.h */ #ifndef _SEARCH_TREE_H #define _SEARCH_TREE_H struct tree_node; typedef struct t ...
- 【java读书笔记】JSTL,高速精通
JSTL并非什么新颖的技术并且非常easy,甚至有人觉得JSTL已经过时了.可是我觉得它既然存在,就有存在的道理.作为技术人员就应该知道它们是什么,怎么使用,有什么长处. JSTL包括两部分:标签库和 ...
- 在Loadrunner中如何用system函数执行系统命令
前提: windows 系统 实现功能:用 LR 中的system函数执行系统命令 相关功能:在LR中利用C函数建立文件,写文件,读文件. 主要相关函数:sprintf/fopen/fgetc/fre ...
- 转载【微信小程序】:微信小程序滚动Tab选项卡:左右可滑动切换(仿某宝)
1.本文转载至:http://blog.csdn.net/sophie_u/article/details/71745125 2.效果: 3.最终效果如上.问题: 1).tab标题总共8个,所以一屏无 ...
- PHP-PHP核心技术与最佳实践阅读
1.对象的实质: 对象就是数据, 对象本身不包含方法, 但是对象有一个"指针"指向一个类, 这个类里可以有方法 2.反射是指在PHP运行状态中, 扩展分析PHP程序, 导出或者提取 ...