ptrofimov / xpmock
PHPUnit:创建模拟对象的简单语法
1.1.5
2014-01-02 16:42 UTC
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: 3.7.*
README
!!! 新版本 1.1.5: 多项改进
PHPUnit 是 PHP 世界的标准测试框架。毫不奇怪,它非常方便。但谈到在 PHPUnit 中模拟对象的方式,许多人抱怨语法有点冗余。他们建议为 PHPUnit 创建模拟对象的许多扩展,如 Mockery(我知道这不仅仅是一个扩展)。
但我确信 PHPUnit 有一个很好的模拟系统。本项目 XPMock 是一种简化这种语法的方法。我需要强调的是,XPMock 并不创建自己的模拟对象。XPMock 只是调用相同的 PHPUnit 方法来创建相同的原生模拟,但更加简单。
写这个
$this->mock('MyClass') ->getBool(true) ->getNumber(1) ->getString('string') ->new();
而不是那个
$mock = $this->getMockBuilder('MyClass') ->setMethods(['getBool', 'getNumber', 'getString']) ->disableOriginalConstructor() ->getMock(); $mock->expects($this->any()) ->method('getBool') ->will($this->returnValue(true)); $mock->expects($this->any()) ->method('getNumber') ->will($this->returnValue(1)); $mock->expects($this->any()) ->method('getString') ->will($this->returnValue('string'));
工具生成功能齐全的原生 PHPUnit 模拟对象。
语法简述
// init mock writer $this->mock('MyClass') // init mock (all methods are real by default) // mock methods // $mock->expects($this->any())->method('getNumber')->will($this->returnValue(null)) ->getNumber() // $mock->expects($this->any())->method('getNumber')->will($this->returnValue(1)) ->getNumber(1) // $mock::staticExpects($this->any())->method('getNumber')->will($this->returnValue(1)) ->getNumber(1) // $mock->expects($this->any())->method('getNumber')->will($this->returnValue(1)) ->getNumber($this->returnValue(1)) // $mock->expects($this->once())->method('getNumber')->will($this->returnValue(null)) ->getNumber($this->once()) // $mock->expects($this->once())->method('getNumber')->will($this->returnValue(1)) ->getNumber(1, $this->once()) // $mock->expects($this->at(0))->method('getNumber')->will($this->returnValue(1)) // $mock->expects($this->at(1))->method('getNumber')->will($this->returnValue(2)) ->getNumber(1, $this->at(0)) ->getNumber(2, $this->at(1)) // $mock->expects($this->once())->method('getNumber')->with(1,2,3)->will($this->returnValue(null)) ->getNumber([1,2,3], $this->once()) // $mock->expects($this->any())->method('getNumber')->with(1,2,3)->will($this->returnValue(1)) ->getNumber([1,2,3], 1) // $mock->expects($this->once())->method('getNumber')->with(1,2,3)->will($this->returnValue(1)) ->getNumber([1,2,3], 1, $this->once()) // $mock->expects($this->any())->method('getNumber')->will($this->returnCallback(function(){})) ->getNumber(function(){}) // $mock->expects($this->any())->method('getNumber')->will($this->throwException(new \Exception(''))) ->getNumber(new \Exception('')) // create mock // $this->getMockBuilder('MyClass')->disableOriginalConstructor()->getMock() ->new() // $this->getMockBuilder('MyClass')->setConstructorArgs([1,2,3])->getMock() ->new(1, 2, 3)
方便的反射方法
// get value of any property: static/non-static, public/protected/private $value = $this->reflect('MyClass')->property; // class name (only static) $value = $this->reflect(new MyClass())->property; // object // set value of any property: static/non-static, public/protected/private property $this->reflect('MyClass')->property = $value; // class name (only static) $this->reflect(new MyClass())->property = $value; // object $this->reflect(new MyClass()) ->__set('property1', $value1) ->__set('property2', $value2); // chain // call any method: static/non-static, public/protected/private $this->reflect('MyClass')->method($arg); // class name (only static) $this->reflect(new MyClass())->method($arg); // object
安装
- 如果您没有 composer,请安装它
- 将 xpmock 添加到您的项目中
composer require ptrofimov/xpmock:dev-master
使用方法
选项 1. 将特质添加到现有测试用例
class MyTestCase extends \PHPUnit_Framework_TestCase { use \Xpmock\TestCaseTrait; }
或选项 2. 从 xpmock 的测试用例扩展您的测试用例
class MyTestCase extends \Xpmock\TestCase { }
NEW
- 如果您需要创建具有某些方法的对象,而类名无关紧要,您可以轻松地这样做
$mock = $this->mock() ->getString('string') ->getNumber(function () { return 2 + 2; }) ->new();
- 模拟静态方法
- 模拟抽象方法
- 创建模拟的简短语法
$mock = $this->mock('MyClass', ['getNumber' => 1]);
- 每个模拟内部的特殊方法 this() 给您提供了更改非公共属性和通过 Xpmock\Reflection 调用模拟的非公共方法的能力
$mock = $this->mock('MyClass')->new(); $mock->this()->protectedProperty = 'value'; $mock->this()->protectedMethod();
- 您可以在模拟方法内部使用 $this 指针
$mock = $this->mock('MyClass', [ 'property' => 1, 'getProperty' => function () { return $this->property; }, ] );
- 现在很容易创建所有方法都返回某些值(例如 null)的模拟(存根)
$mock = $this->mock('MyClass', null);
- 非常期待:现在可以使用魔法方法 mock() 调整创建后的模拟
$myClass = $this->mock('MyClass', null); $myClass->getNumber(); // null $myClass->mock() ->getNumber(1); $myClass->getNumber(); // 1