談php設(shè)計(jì)模式介紹——偽對象模式(5)_PHP教程
推薦:解析php字符串處理函數(shù)addcslashes 為字符串里面的部分字符添加反斜線轉(zhuǎn)義字符 addslashes 用指定的方式對字符串里面的字符進(jìn)行轉(zhuǎn)義 bin2hex 將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成十六進(jìn)制表示 chr 返回一個(gè)字符的ASCII碼 chunk_split 按一定的字符長度將字符串分割成小塊 convert_cyr_string 將斯
現(xiàn)在讓我們來創(chuàng)建一些測試的實(shí)例來詳細(xì)說明重構(gòu)后的運(yùn)用程序應(yīng)該有的功能。
require_once ‘simpletest/unit_tester.php’;
require_once ‘simpletest/reporter.php’; require_once ‘simpletest/mock_objects.php’; require_once ‘simpletest/web_tester.php’;
require_once ‘classes.inc.php’; Session::init();
class PageWebTestCase extends WebTestCase { /*...*/ } class ResponseTestCase extends UnitTestCase { /*...*/ } class UserLoginTestCase extends UnitTestCase { /*...*/ } class SessionTestCase extends UnitTestCase { /*...*/ }
class PageDirectorTestCase extends UnitTestCase { /*...*/ }
$test = new GroupTest(‘Application PHP4 Unit Test’);
$test->addTestCase(new PageWebTestCase);
$test->addTestCase(new ResponseTestCase);
$test->addTestCase(new UserLoginTestCase);
$test->addTestCase(new SessionTestCase);
$test->addTestCase(new PageDirectorTestCase);
這段代碼或多或少的展示了一個(gè)典型的運(yùn)用程序的測試文件該是何種模樣。它一開始就包含了一些SimpleTest文件,也包括了用偽對象來測試的mock_object.php文件。接著,那些輔助類被包含進(jìn)來,方法Session::init()被調(diào)用,seesion開始。
緊接著的全是以“安全無害”為目標(biāo)而開始的測試實(shí)例,類WebTestCase確保所有程序按要求執(zhí)行, 然后是單獨(dú)的用于新設(shè)計(jì)的類的測試(盡管這種類本章不會詳述)。最后是我們接下去會討論的PageDirectorTestCase類。
類PageDirector的核心任務(wù)是協(xié)調(diào)類Session和類Response的對象,產(chǎn)生最終的網(wǎng)頁輸出結(jié)果。
Mock::Generate(‘Session’);
Mock::Generate(‘Response’);
define(‘SELF’, ‘testvalue’);
class PageDirectorTestCase extends UnitTestCase {
// ...
}
在這段代碼的一開始,Mock::generate()創(chuàng)建了偽對象類的定義并定義了一個(gè)后面將要用到的常量。
假設(shè)對類Session 和類 Response的測試已經(jīng)存在,下一步就是創(chuàng)建偽Session來模擬類 Session的狀態(tài)。這個(gè)偽對象的設(shè)置和我們一開始所演示的例子極其類似。
因?yàn)镻ageDirector::run()方法正回顯內(nèi)容,你可以用輸出緩存內(nèi)容的辦法來捕獲它,看看是否正確。
class PageDirectorTestCase extends UnitTestCase {
// ...
function TestLoggedOutContent() {
$session =& new MockSession($this);
$session->setReturnValue(‘get’, null, array(‘user_name’));
$session->expectOnce(‘get’, array(‘user_name’));
$page =& new PageDirector($session, new Response);
ob_start();
$page->run();
$result = ob_get_clean();
$this->assertNoUnwantedPattern(‘/secret.*content/i’, $result);
$this->assertWantedPattern(‘/<form.*<input[^>]*text[^>]*’
.’name.*<input[^>]*password[^>]*passwd/ims’
,$result);
$session->tally();
}
}
這段代碼證明了在SimpleTest中使用偽對象的必要性。我們來看看其中創(chuàng)建偽對象的一行代碼$session =&new MockSession($this)。你可以使用繼承自SimpleStub類(參見http://simpletest.sf.net/SimpleTest/MockObjects/SimpleStub.html#sec-methodsummary)的方法來創(chuàng)建你所希望的從對象(如同你在測試代碼時(shí)所做的那樣)返回的結(jié)果.下一步,實(shí)例化PageDirector類并用MockSession代替正式使用時(shí)的類來實(shí)例化相關(guān)代碼。
注:setReturnValue()方法
setReturnValue()方法通過指定當(dāng)偽對象的特定方法被調(diào)用時(shí)返回何值來讓偽對象以一個(gè)“替身”的身份融入代碼。已經(jīng)有了一些這種方法的變體:比如指定以一定次序返回一系列值的做法,還有以參數(shù)代替值來返回結(jié)果的做法。
expectOnce()方法
expectOnce()方法通過建立一些假想,這些假想是關(guān)于什么時(shí)候方法被調(diào)用以及多久調(diào)用一次,來允許你的偽對象以“批評者”的角色來測試代碼。這些假想當(dāng)你在測試中調(diào)用偽對象的tally()方法時(shí)會被報(bào)告。
class PageDirector {
var $session;
var $response;
function PageDirector(&$session, &$response) {
$this->session =& $session;
$this->response =& $response;
}
}
因?yàn)镻ageDirector類認(rèn)為自己不是處于一個(gè)測試環(huán)境而是處于一個(gè)真實(shí)正常的運(yùn)用程序環(huán)境中,它回顯結(jié)果到瀏覽器。既然你實(shí)際上在測試時(shí)并不希望這個(gè)動作,你就可以通過PHP輸出緩存的特性(參見http://php.net/outcontrol)來捕獲執(zhí)行時(shí)它往瀏覽器發(fā)送了什么。
class PageDirector {
// ...
function run() {
if (!$this->isLoggedIn()) {
$this->showLogin();
}
$this->response->display();
}
function isLoggedIn() {
return ($this->session->get(‘user_name’)) ? true : false;
}
function showLogin() {
$this->response->addBody(‘<form method=”post”>’);
$this->response->addBody(‘Name:<input type=”text” name=”name”>’);
$this->response->addBody(“\n”);
$this->response->addBody(
‘Password:<input type=”password” name=”passwd”>’);
$this->response->addBody(“\n”);
$this->response->addBody(‘<input type=”submit” value=”Login”>’);
$this->response->addBody(‘</form>’);
}
}
如同這段程序代碼一樣,測試代碼本身也可以進(jìn)行重構(gòu)。在本例中,你可以看到緩存輸出的訣竅是其將被多次復(fù)用,因此使用“析構(gòu)法”重構(gòu)可以使測試本身簡化。(重新調(diào)用的那些以“test”為開頭的方法是隨整個(gè)測試一起自動運(yùn)行的;你也可以自己創(chuàng)建一些使測試更簡潔的方法。)
分享:怎樣把握技巧開發(fā)PHP網(wǎng)站1.使用 ip2long() 和 long2ip() 函數(shù)來把 IP 地址轉(zhuǎn)化成整型存儲到數(shù)據(jù)庫里。這種方法把存儲空間降到了接近四分之一(char(15) 的 15 個(gè)字節(jié)對整形的 4 個(gè)字節(jié)),計(jì)算一個(gè)特定的地址是不是在一個(gè)區(qū)段內(nèi)頁更簡單了,而且加快了搜索和排序的速度(雖然有時(shí)僅
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁面代碼執(zhí)行時(shí)間
- PHP中獎(jiǎng)概率的抽獎(jiǎng)算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問控制的和運(yùn)算符優(yōu)先級介紹
- 關(guān)于PHP語言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國語言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
- 相關(guān)鏈接:
- 教程說明:
PHP教程-談php設(shè)計(jì)模式介紹——偽對象模式(5)
。