2012-11-21 179 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