首页 > 代码库 > JUnit4.8.2源代码分析-4 RunNotifier与RunListener
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的源代码:
public interface MouseListener extendsEventListener {
publicvoid mouseClicked(MouseEvent e);
publicvoid mousePressed(MouseEvent e);
publicvoid mouseReleased(MouseEvent e);
publicvoid mouseEntered(MouseEvent e);
publicvoid mouseExited(MouseEvent e);
}
那么,RunListener处理测试运行的7个动作:
1. publicvoid testRunStarted(Description description)
在所有测试将要运行前的动作。如同运动会比赛前召开开幕式一样。
2. public void testStarted(Description description)
在一个测试(如@Test)开始之前的动作。
3. public void testFinished(Description description)
对应testStarted,一个测试结束后的动作。不论测试succeeds or fails。
4.public void testRunFinished(Resultresult)
对应testRunStarted,所有测试运行后的动作。
5.public void testIgnored(Description description)
遇到一个@Ignore测试方法是的动作。
6. public void testFailure(Failurefailure)
若测试失败,调用这个动作。
7. public void testAssumptionFailure(Failure failure)
与断言不同,Assume定义了4个静态的测试条件,如assumeTrue(boolean b)等。如果条件不满足时调用本方法。
RunListener定义了这7个空方法,地位等同于MouseAdapter,yqj2065觉得最好还是用abstract修饰它。
注意:回调接口的参数,用于将数据传递给上层模块。由于7个动作发生的时机不同,RunListener中使用了Description、Failure和Result封装回调接口所需的数据。
org.junit.runner.notification.Failure封装的数据有:final Description、final Throwable。
Result封装的数据有:
privateAtomicInteger fCount // the number of tests run
privateAtomicInteger fIgnoreCount// the number of tests ignored
privatefinal List<Failure> fFailures
privatelong fRunTime// milliseconds for run the entire suite
privatelong fStartTime;
Result有一些get方法,还提供了几个便利方法如
public booleanwasSuccessful() //fFailures .size()为0f返回true
还有一个自带的私有内部类Listener,用于产生Result封装的数据。例如
public voidtestFinished(Description description) throws Exception {
fCount.getAndIncrement();
}
把这个代码放在testStarted中也可以。(可以删除这些类型)
2. TextListener
具体监听器org.junit.internal.TextListener将以打印文本的形式处理7种动作。
正如我们常用的System.out.println(),TextListener的打印工作由一个java.io.PrintStream完成,而该对象由System或JUnitSystem指定。顺便说明接口JUnitSystem有两个方法:exit(int i)和PrintStream out();其子类RealSystem代码
public class RealSystem implements JUnitSystem {
publicvoid exit(int code) { System.exit(code); }
publicPrintStream out() { returnSystem.out; }
}
TextListener为编写我们自己的Listener提供了一个简单的例子。(可以删除这些类型)
3. RunNotifier
被观察目标Subject/Notifier,某种事件发生或数据/状态改变后,自动调用doNotify()转而调用回调。RunNotifier是一个半截子的Subject,它维护一个注册表List<RunListener>,有addListener、removeListener操作;但是它的7个fireXxx方法触发对回调接口的调用,不涉及某种事件发生或数据/状态改变。这就是典型的二传手式委派。真正的幕后的Subject是谁呢?
因此这个二传手是一个孤零零的类,没有子类,所有public方法都在注释中声称为Internaluse only。
本文涉及的类型:org.junit.runner.notification.RunListener及其子类org.junit.internal.TextListener(JUnitSystem和RealSystem)、数据Description、Failure和Result、RunNotifier
涉及的设计模式:观察者模式。
JUnit4.8.2源代码分析-4 RunNotifier与RunListener