下面的代码段演示了缓存输出被重构为runPage方法的结果,它给人的感觉就像是当用户登录时另一个对输出的测试。
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); $result = $this->runPage($page); $this->assertNoUnwantedPattern(‘/secret.*content/i’, $result); $this->assertWantedPattern(‘/<form.*<input[^>]*text[^>]*’ .’name.*<input[^>]*password[^>]*passwd/ims’ ,$result); $session->tally(); } function TestLoggedInContent() { $session =& new MockSession($this); $session->setReturnValue(‘get’, ‘admin’, array(‘user_name’)); $session->expectAtLeastOnce(‘get’); $page =& new PageDirector($session, new Response); $result = $this->runPage($page); $this->assertWantedPattern(‘/secret.*content/i’, $result); $this->assertNoUnwantedPattern(‘/<form.*<input[^>]*text[^>]*’ .’name.*<input[^>]*password[^>]*passwd/ims’ ,$result); $session->tally(); } function runPage(&$page) { ob_start(); $page->run(); return ob_get_clean(); } }
接下来,将加入一个检查条件到PageDirector::run()方法来看看用户是否已经登录并决定显示什么模板:
class PageDirector { // ... function run() { if ($this->isLoggedIn()) { $this->showPage( new UserLogin($this->session->get(‘user_name’))); } else { $this->showLogin(); } $this->response->display(); } function showPage(&$user) { $vars = array( ‘name’ => $user->name() ,’self’ => SELF ); $this->response->addBodyTemplate(‘page.tpl’, $vars); } }
page.tpl看上去可能像这样:
Welcome <?php echo $name; ?> <br>Super secret member only content here. <a href=”<?php echo $self; ?>?clear”>Logout</a>
此时,MockSession扮演了ServerStub的角色来控制决定用户是否登录的条件。它的功能也类似评判者,决定这个信息是否通过如下两个途径被正确的使用:一个是明确地被预先定义并通过tally()被验证,另一个是不直接的生成正确的输出,而是通过ServerStub返回的值来生成。
为了继续重构这段代码,下一步要跳到前面的进程。将要做两个动作:清除已经登录的用户和验证登录页面提交的用户名和密码是否存在。
让我们从注销功能上开始:
class PageDirectorTestCase extends UnitTestCase { // ... function TestClearLoginFunctionality() { $_REQUEST[‘clear’] = null; $session =& new MockSession($this); $session->expectOnce(‘clear’, array(‘user_name’)); $session->setReturnValue(‘get’, null, array(‘user_name’)); $session->expectAtLeastOnce(‘get’); $response = new MockResponse($this); $response->expectOnce(‘redirect’, array(SELF)); $page =& new PageDirector($session, $response); $this->assertEqual(‘’, $this->runPage($page)); $response->tally(); $session->tally(); unset($_REQUEST[‘clear’]); } }
在这段代码中,response是个伪对象,然而,一旦在Response::redirect()方法中调用了exit(),脚本将会停止执行。由于伪对象的存在,你可以核实方法是否被调用和方法传回了什么参数,且不会产生任何负面影响——如脚本停止——或被实际执行。
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之伪对象模式 [5] 下一页 php设计模式介绍之伪对象模式 [7]
◎进入论坛网络编程版块参加讨论
|