我试图使用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 :(得分: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
}
}