...
setUp();
testXXX();
tearDown();
用过JUnit的对这些应该是烂熟于胸了,这三部曲简述了JUnit的最基本的操作过程,JUnit的设计者为了保证这三部操作能像原子操作般执行,使用了一个很通用的设计模式,Template pattern, 典型的模板模式基本上是按照下面的方式来设计的:
/**
*定义一个抽象的类,并定义几个要步骤化的抽象方法,
×把这些操作交付给起子孙后代去实现,
*再定义一个总控这个步骤的方法--模板方法,这里对manipulate做了final修饰,
×不让其子类改写,当然如果开明点,也可以把这个final给去掉,这样其子孙也
×也有权利设计这个操作内容了。
*/
public abstract class A{
protected abstract void operOne();
protected abstract void operTwo();
protected abstract void operThree();
public final void manipulate(){
operOne();
operTwo();
operThree();
}
}
/**
*继承A,并实现自己的操作
*/
public class SubA{
protected void operOne(){
System.out.pritln("step one");
}
protected void operTwo(){
System.out.pritln("step two");
}
protected void operThree(){
System.out.pritln("step three");
}
}
JUnit是这样做的吗?肯定不是了。那是怎样处理的呢?
让我们来赏析一下JUnit的内核源码片段:
package junit.framework;
import java.util.Vector;
import java.util.Enumeration;
/**
* A <code>TestResult</code> collects the results of executing
* a test case. It is an instance of the Collecting Parameter pattern.
* The test framework distinguishes between <i>failures</i> and <i>errors</i>.
* A failure is anticipated and checked for with assertions. Errors are
* unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
*
* @see Test
*/
public class TestResult extends Object {
...
/**
* Runs a TestCase.
*/
public void runProtected(final Test test, Protectable p) {
try {
p.protect();
}
catch (AssertionFailedError e) {
addFailure(test, e);
}
catch (ThreadDeath e) { // don't catch ThreadDeath by accident
throw e;
}
catch (Throwable e) {
addError(test, e);
}
}
/**
* Runs a TestCase.
*/
protected void run(final TestCase test) {
startTest(test);
Protectable p= new Protectable() {
public void protect() throws Throwable {
test.runBare();
}
};
runProtected(test, p);
endTest(test);
}
...
}
以上是TestResult摘录的一个片段,这里要强调的是接口Protectable,这个接口就是用来保护setUp(),runBase(),tearDown()操作的,也就是说在执行某个测试的时候系统一定要经过这些步骤,当然JUnit的作者是在哪些地方去实现了Protectabe接口的呢?笔者去跟踪了源码,实现接口的位置有两处,如下:
public abstract class TestCase extends Assert implements Test {
...
/**
* Runs the bare test sequence.
* @exception Throwable if any exception is thrown
*/
public void runBare() throws Throwable {
setUp();
try {
runTest();
}
finally {
tearDown();
}
}
public TestResult run() {
TestResult result= createResult();
run(result);
return result;
}
...
}
另外一处:
package junit.extensions;
import junit.framework.*;
/**
* A Decorator to set up and tear down additional fixture state.
* Subclass TestSetup and insert it into your tests when you want
* to set up additional state once before the tests are run.
*/
public class TestSetup extends TestDecorator {
public TestSetup(Test test) {
super(test);
}
public void run(final TestResult result) {
Protectable p= new Protectable() {
public void protect() throws Exception {
setUp();
basicRun(result);
tearDown();
}
};
result.runProtected(this, p);
}
/**
* Sets up the fixture. Override to set up additional fixture
* state.
*/
protected void setUp() throws Exception {
}
/**
* Tears down the fixture. Override to tear down the additional
* fixture state.
*/
protected void tearDown() throws Exception {
}
}
到这想必大家已经基本上理解了设计者的意图了,但相比较于继承父类的方式来实现模板化,使用接口更加体现了系统的灵活性,假设前面提到的类A是由第三方提供的component,但这个component却没有提供类似的模板方面,这个时候我们可以考虑使用模板化接口来解决这个问题,但是作者可不是直接实现接口,而是采用方法中调用Protectable的方式来事处理了,这更加体现了系统的灵活度(当然这也是Inversion Of Contorl理念之一)。
分享到:
相关推荐
Junit设计模式分析 Junit设计模式分析 Junit设计模式分析 Junit设计模式分析
JUnit设计模式分析 详细讲解JUnit源码中用到的设计模式
重点讲到了junit里用到了那些设计模式.
Junit设计模式分析,Junit设计模式分析.pdf,Junit设计模式分析.pdf,Junit设计模式分析.pdf
Junit框架是设计模式应用的经典案例,从中你可以更好的学习和掌握设计模式的使用!
Junit所使用的设计模式.doc Junit所使用的设计模式.doc
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage,包含依赖包:junit-jupiter-5.5.1.jar,junit-jupiter-engine-5.5.1.jar,junit-jupiter-params-5.5.1.jar,junit-platform-launcher-1.5.1.jar,junit-...
一个参考Junit的设计模式ppt 一个参考Junit的设计模式ppt
Junit设计模式分析(带源码)
junit4.1junit4.1junit4.1junit4.1junit4.1
Files contained in junit4-4.8.2.jar: LICENSE.txt META-INF/MANIFEST.MF junit.extensions.ActiveTestSuite.class junit.extensions.RepeatedTest.class junit.extensions.TestDecorator.class junit.extensions...
JUNIT介绍.JUNIT介绍.JUNIT介绍.JUNIT介绍.
NULL 博文链接:https://liqun.iteye.com/blog/391388
JUnit API JUnit API JUnit API JUnit API JUnit API
使用JUNIT框架实现的设计模式验证演示代码
• JUnit 优雅简洁。没那么复杂,花费时间较少。 • JUnit 测试可以自动运行并且检查自身结果并提供即时反馈。所以也没有必要人工梳理测试结果的报告。 • JUnit 测试可以被组织为测试套件,包含测试用例,甚至其他...
Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验Junit入门实验
关于junit的介绍 关于关于junit的介绍关于junit的介绍关于junit的介绍关于junit的介绍关于junit的介绍关于junit的介绍