一 合成模式的介紹
合成模式將對象組織到樹結構中可以用來描述整體與部分的關係。合成模式可以使客戶端將單純元素與複合元素同等看待。
合成模式之於面向對象如同樹結構之於結構化編程。
二Junit中對合成模式的使用分析
圖一
Test接口、TestCase類與TestSuite類之間的靜態類圖如圖一所示。
Test接口只含有兩個方法,其源碼如下所示:
package junit.framework;
/**
* A <em>Test</em> can be run and collect its results.
*
* @see TestResult
*/
public interface Test{
/**
* Counts the number oftest cases that will be run by this test.
*/
public abstract int countTestCases();
/**
* Runs a test and collectsits result in a TestResult instance.
*/
public abstract void run(TestResult result);
}
Test接口不包含用來管理子類對象的方法,而是將之置於TestSuite類裏,TestSuite類與合成模式相關的關鍵代碼如下:
*/
public class TestSuite implements Test {
……
private String fName;
private Vector<Test> fTests= new Vector<Test>(10); // Cannot convert this to List because it is useddirectly by some test runners
……
/**
* Adds a test to thesuite.
*/
public void addTest(Test test) {
fTests.add(test);
}
/**
* Adds the tests from thegiven class to the suite
*/
public void addTestSuite(Class<? extends TestCase> testClass) {
addTest(new TestSuite(testClass));
}
/**
* Counts the number oftest cases that will be run by this test.
*/
public int countTestCases() {
int count= 0;
for (Test each : fTests)
count+= each.countTestCases();
return count;
}
……
/**
* Runs the tests andcollects their result in a TestResult.
*/
public void run(TestResultresult) {
for (Test each : fTests) {
if (result.shouldStop() )
break;
runTest(each, result);
}
}
public void runTest(Test test, TestResult result) {
test.run(result);
}
}
TestSuite類持有Test接口屬性:private Vector<Test> fTests=new Vector<Test>(10);故fTests既可以添加TestCase又可以添加TestSuite對象,以此形成一個樹結構。
而TestCase類屬於葉子節點,不持有Test接口的屬性。其主要代碼如下:
public abstract class TestCase extends Assertimplements Test {
……
/**
* Runs the test case andcollects the results in TestResult.
*/
public void run(TestResult result) {
result.run(this);
}
……
}
這樣葉子節點裏無管理子類對象的方法,因此客戶端對葉子對象使用這些方法時程序會在編譯時期出錯。
這種合成模式是為安全方式的合成模式。
三 Junit中TestSuite的使用
1. 新建一個單元測試類繼承TestSuite類。
public class RunAllTest extends TestSuite
2. 新建一個靜態方法返回類型為Test
public static Test suite()
P.S.:該Test的類型為: junit.framework.Test而非org.junit.Test
3. 新建TestSuite對象
TestSuite suite = newTestSuite();
4. 將需運行的測試用例載入至TestSuite對象。
suite.addTestSuite(SeverityTest.class);
suite.addTest(new SeverityTest(“testGetSeverity_Good”));
5. 返回TestSuite對象
四 TestSuite的價值
TestSuitegives you flexibility in the grouping and granularity of test cases.
因為我們可以在設定檔裡配置一次運行多個TestCase;可以解決單元測試順序問題。