编写已编写代码的单元测试有时很有趣。
我正在编写以下代码的测试用例(示例):
<?php
class mockPrivate {
public static function one($a){
$var = static::_two($a);
return $var;
}
private static function _two($a){
return $a+1;
}
}
?>
测试类是这样的:
<?php
require_once 'mockPvt.php';
class mockPrivate_test extends PHPUnit_Framework_TestCase {
public $classMock;
protected function setUp(){
$this->classMock = $this->getMock('mockPrivate', array('_two'));
}
public function test_one(){
$a = 1;
$retVal = 2;
$classmock = $this->classMock;
$classmock::staticExpects($this->once())
->method('_two')
->with($a)
->will($this->returnValue($retVal));
$value = $classmock::one($a);
$this->assertEquals($value, $retVal);
}
}
?>
在$ phpunit mockPrivate_test.php
之后运行时出现此错误:
PHP Fatal error: Call to private method Mock_mockPrivate_531a1619::_two() from context 'mockPrivate' in /data/www/dev-sumit/tests/example
s/mockPvt.php on line 6
但如果我改变了
private static function _two()
to
public static function _two() or
protected static function _two()
它完全正常。由于这是遗留代码,因此我无法更改private to public/protected
。那么有什么办法我可以测试一个函数或者这是phpunit的限制吗?
答案 0 :(得分:2)
另一种选择是创建一个扩展mockPrivate的类,允许访问您想要测试的对象。你的工程师应该长时间地思考为什么某些东西是私有的(因为这意味着这个类不容易扩展)。还要记住,如果需要覆盖它返回的内容,可以模拟测试类。
class Test_MockPrivate extends MockPrivate
{
/**
* Allow public access to normally protected function
*/
public static function _two($a){
return parent::_two($a);
}
}
// Code to force the return value of a now public function
$mock = $this->getMock('Test_MockPrivate', array('_two'));
$mock->expects($this->any())
->method('_two')
->will($this->returnValue('Some Overridden Value');
答案 1 :(得分:1)
您可以使用反射来更改方法的可见性。您可以在中找到更多信息 PHP object, how to reference?
答案 2 :(得分:0)
使用模拟和反射...(发布此解决方案,因为这是google的最佳结果)
$oMock = $this->getMock("Your_class", array('methodToOverride'));
$oMock->expects( $this->any() )
->method('methodToOverride')
->will( $this->returnValue( true ) );
$oReflection = new ReflectionClass("Your_Class");
$oMethod = $oReflection->getMethod('privateMethodToInvoke');
$oMethod->setAccessible( true );
$oMethod->invoke( $oMock );