上文:《PHP設(shè)計(jì)模式介紹》第五章 注冊模式
《PHP設(shè)計(jì)模式介紹》第六章 偽對象模式
面向?qū)ο蟮木幊讨载S富多彩,部分是由于對象間的相互聯(lián)系與作用。一個(gè)單一的對象就能封裝一個(gè)復(fù)雜的子系統(tǒng),使那些很復(fù)雜的操作能夠通過一些方法的調(diào)用而簡化。(無所不在的數(shù)據(jù)庫連接就是這樣的一個(gè)對象實(shí)例。)
然而經(jīng)常有這樣的情況,對象間的交互性是如此復(fù)雜以至于我們不得不面對類似“先有雞還是先有蛋”這樣傷腦筋的問題:如何創(chuàng)建并測試這樣一個(gè)對象,他要么依賴于很多已創(chuàng)建的對象,要么依賴于其他一些難以意識(shí)到的情況,如整個(gè)數(shù)據(jù)庫的創(chuàng)建和測試。
問題
如何分隔并測試一個(gè)與其他對象和資源有關(guān)的代碼段?又如何再創(chuàng)建一個(gè)或多個(gè)對象、程序來驗(yàn)證你的代碼能正常運(yùn)行?
解決方案
當(dāng)用situ(或在一個(gè)仿真的程序環(huán)境中)測試一個(gè)對象代價(jià)不菲或困難重重時(shí),就可用偽對象來模擬這個(gè)行為。偽對象有同真實(shí)對象一樣的接口,但卻能提供預(yù)編譯響應(yīng),能跟蹤方法調(diào)用,并驗(yàn)證調(diào)用次序。
偽對象是測試的“特別力量”。他們被秘密訓(xùn)練,滲透進(jìn)目標(biāo)代碼,模擬并監(jiān)視通信方式,回報(bào)結(jié)果。偽對象有助于查找和消除程序漏洞并能支持更多正常調(diào)試環(huán)境下的“防危險(xiǎn)”操作。
注:The ServerStub 偽對象模式是另一種測試模式ServerStub的擴(kuò)展。ServerStub模式替代一個(gè)資源并返回其方法所調(diào)用的相應(yīng)值。當(dāng)其參與指定次序的方法的調(diào)用時(shí)ServerStub就成了偽對象。
其并非是一個(gè)設(shè)計(jì)模式
本章與其他章不同,因?yàn)閭螌ο笫且粋(gè)測試模式而不是設(shè)計(jì)模式。這類似于一個(gè)附加的章節(jié),但對它的使用 確實(shí)很值得你納入到編碼進(jìn)程中。另一個(gè)不同是我們不再關(guān)注這個(gè)模式如何編碼之類的基礎(chǔ)問題,而是強(qiáng)調(diào) 如何在SimpleTest中使用偽對象。
本章先舉一個(gè)非常簡單的例子來示范SimpleTest下偽對象的基本機(jī)制。然后向你演示如何使用偽對象幫助重構(gòu)已有代碼與如何測試新的解決方案。
樣本代碼
偽對象是對象在測試中的一個(gè)替代品,用它測試代碼更加簡便。例如,替代一個(gè)真實(shí)的數(shù)據(jù)連接——這個(gè)真實(shí)的數(shù)據(jù)連接由于一些原因而不能實(shí)際連接——你就可以創(chuàng)建一個(gè)偽對象來模擬。這意味著偽對象需要準(zhǔn)確地回應(yīng)代碼中所調(diào)用的相同的應(yīng)用程序接口。
讓我們創(chuàng)建一個(gè)偽對象來替代一個(gè)簡單的名為Accumulator的類,這是一個(gè)求和的類。如下是最初的Accumulator類:
// PHP4 class Accumulator { var $total=0; function add($item) { $this->total += $item; } function total() { return $this->total; } }
這個(gè)類中add()函數(shù)先累加值到$total變量中,再交由total()函數(shù)返回 。 一個(gè)簡單的累加也可以如下面這樣(下面的代碼被編寫為一個(gè)函數(shù),但它也可以寫成一個(gè)類)。
function calc_total($items, &$sum) { foreach($items as $item) { $sum->add($item); } } function calc_tax(&$amount, $rate=0.07) { return round($amount->total() * $rate,2); }
第一個(gè)函數(shù)calc_total()用一個(gè)累加的動(dòng)作求一系列值的和。下面是簡單的測試:
class MockObjectTestCase extends UnitTestCase { function testCalcTotal() { $sum =& new Accumulator; calc_total(array(1,2,3), $sum); $this->assertEqual(6, $sum->total()); } }
讓我們關(guān)注第二個(gè)例子。假設(shè)實(shí)現(xiàn)一個(gè)真實(shí)的累加動(dòng)作的代價(jià)很大。那么用一個(gè)簡單的對象來替代它并回應(yīng)相關(guān)代碼就是很好的做法了。使用SimpleTest,你可以用如下代碼創(chuàng)建一個(gè)偽累加動(dòng)作:
Mock::generate(‘Accumulator’); class MockObjectTestCase extends UnitTestCase {
// ... function testCalcTax() { $amount =& new MockAccumulator($this); $amount->setReturnValue(‘total’,200); $this->assertEqual( 14, calc_tax($amount)); } }
為了使用偽對象,具有代表性的做法是你親自寫一個(gè)新類(并不要求馬上做)。幸運(yùn)的是,SimpleTest有一種容易的手段來實(shí)現(xiàn) Mock::generate() 方法。
出處:phpchina
責(zé)任編輯:bluehearts
上一頁 下一頁 php設(shè)計(jì)模式介紹之偽對象模式 [2]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|