ptrofimov/xpmock

PHPUnit:创建模拟对象的简单语法

1.1.5 2014-01-02 16:42 UTC

This package is not auto-updated.

Last update: 2024-09-21 13:40:05 UTC


README

Build Status Latest Stable Version Total Downloads

简介 [英文] [俄语]

!!! 新版本 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

安装

  1. 如果您没有 composer,请安装它
  2. 将 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

  1. 如果您需要创建具有某些方法的对象,而类名无关紧要,您可以轻松地这样做
$mock = $this->mock()
    ->getString('string')
    ->getNumber(function () {
        return 2 + 2;
    })
    ->new();
  1. 模拟静态方法
  2. 模拟抽象方法
  3. 创建模拟的简短语法
$mock = $this->mock('MyClass', ['getNumber' => 1]);
  1. 每个模拟内部的特殊方法 this() 给您提供了更改非公共属性和通过 Xpmock\Reflection 调用模拟的非公共方法的能力
$mock = $this->mock('MyClass')->new();
$mock->this()->protectedProperty = 'value';
$mock->this()->protectedMethod();
  1. 您可以在模拟方法内部使用 $this 指针
$mock = $this->mock('MyClass',
    [
        'property' => 1,
        'getProperty' => function () {
            return $this->property;
        },
    ]
);
  1. 现在很容易创建所有方法都返回某些值(例如 null)的模拟(存根)
$mock = $this->mock('MyClass', null);
  1. 非常期待:现在可以使用魔法方法 mock() 调整创建后的模拟
$myClass = $this->mock('MyClass', null);
$myClass->getNumber(); // null
$myClass->mock()
    ->getNumber(1);
$myClass->getNumber(); // 1