2012-11-21 225 views
3

我正在嘗試使用PHPunit來嘲笑一些依賴項,但我的模擬對象似乎並沒有工作。PHPunit測試不嘲笑依賴關係

Logger.php

class Logger 
{ 
    function __construct($log_path) 
    { 
     // make sure file exists, open file handle 
    } 
    function write($msg) 
    { 
     // write message to log 
    } 
} 

MyCurl.php

class MyCurl 
{ 
    function __construct($url) 
    { 
     // set my default curl options 
    } 
    function exec() 
    { 
     // execute curl request and capture output 
    } 
} 

function_x.php

require_once("Logger.php"); 
require_once("MyCurl.php"); 
function function_x($params) 
{ 
    // set some stuff up; 
    $LoggerObj = new Logger($filepath); 
    $CurlObj = new MyCurl($url); 
    // more stuff 
    $LoggerObj->write($CurlObj->exec()); 
    // do stuff 
    return $result; 
} 

function_x_Test.php

require_once('function_x.php'); 
class functionXTest extends PHPUnit_Framework_TestCase 
{ 
    public function testCleanRun() 
    { 

     $MockLogger = $this->getMockBuilder('Logger')->disableOriginalConstructor()->setMethods(array('write', '__destruct'))->getMock(); 
     $MockLogger->expects($this->any())->method('write')->will($this->returnValue(true)); 

     $MockCurl = $this->getMockBuilder('MyCurl')->disableOriginalConstructor()->setMethods(array('exec', '__destruct'))->getMock(); 
     $MockCurl->expects($this->any())->method('exec')->will($this->returnValue('exec returnz')); 

     $result = function_x($params); 
     // start assertions with function_x results 
    } 
} 

當我運行我的測試時,它顯示正在爲我的Logger類調用原始構造函數。它似乎沒有使用嘲笑類。我假設如果我在測試中宣佈了模擬,所有對原始類的調用都會被嘲笑,從而消除這些依賴關係。顯然,我做錯了什麼。任何人都可以借給我一個援助之手或指向正確的方向嗎?謝謝!

+0

啊,依賴注入。是的,它已經超出了我的想法,但我覺得有點骯髒改變'生產代碼'以採取'測試數據'。然而,它的功能就像一個魅力。感謝一噸公噸! – sethammons

回答

3

嘲笑正在取代一個對象(請參閱documentation),而不是一個類。

所以,讓你的例子有嘲弄的工作,你應該注入的對象(dependency injection):

function function_x($params, $logger = null, $curl = null) 
{ 
    //Here, you can set logger and curl if they are null. 
    // only do this to make sure legacy code works. 
    if(!$logger) { 
    $logger = new Logger(); 
    } 
    if(!$curl) { 
    $curl = new MYCurl(); 
    } 

    //rest of your code 
} 

,並在您的測試,你叫

require_once('function_x.php'); 
class functionXTest extends PHPUnit_Framework_TestCase 
{ 
    public function testCleanRun() 
    { 

    $MockLogger = $this->getMockBuilder('Logger')->disableOriginalConstructor()->setMethods(array('write', '__destruct'))->getMock(); 
    $MockLogger->expects($this->any())->method('write')->will($this->returnValue(true)); 

    $MockCurl = $this->getMockBuilder('MyCurl')->disableOriginalConstructor()->setMethods(array('exec', '__destruct'))->getMock(); 
    $MockCurl->expects($this->any())->method('exec')->will($this->returnValue('exec returnz')); 

    $result = function_x($params, $MockLogger, $MockCurl); 
    // start assertions with function_x results 
    } 
} 
+0

謝謝!依賴注入。似乎是這個問題的事實上的解決方案,特別是在PHP中。 – sethammons