承接 ptrofimov/xpmock 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ptrofimov/xpmock

Composer 安装命令:

composer require ptrofimov/xpmock

包简介

PHPUnit: simple syntax to create mock-objects

README 文档

README

Build Status Latest Stable Version Total Downloads

Introduction [in English] [на русском]

!!! New version 1.1.5: multiple improvements

PHPUnit is standard testing framework in PHP world. No wonder - it is nifty. But speaking about way of mocking objects in PHPUnit many people complain on a bit redundant syntax. They suggest many addons for PHPUnit to create mocks like Mockery (I know this is not just addon).

But I am sure PHPUnit has well-developed mocking system. And this project XPMock is a way to simplify this syntax a bit. I need to underline that XPMock doesn't create some own mock objects. XPMock just calls the same PHPUnit methods creating the same native mocks but much simpler.

Write this

$this->mock('MyClass')
    ->getBool(true)
    ->getNumber(1)
    ->getString('string')
    ->new();

instead of that

$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'));

Tool generates full-functional native PHPUnit mocks.

Syntax short description

// 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)

Handy reflection methods

// 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

Installation

  1. If you don't have composer, install it
  2. Add xpmock to your project
composer require ptrofimov/xpmock:dev-master

Usage

Option 1. Add trait to existing test case:

class MyTestCase extends \PHPUnit_Framework_TestCase
{
    use \Xpmock\TestCaseTrait;
}

OR Option 2. Extend your test case from xpmock's one:

class MyTestCase extends \Xpmock\TestCase
{
    
}

NEW

  1. If you need to create object with some methods and classname doesn't matter, you could easily do it like this:
$mock = $this->mock()
    ->getString('string')
    ->getNumber(function () {
        return 2 + 2;
    })
    ->new();
  1. Mocking static methods
  2. Mocking abstract methods
  3. Brief syntax to create mocks
$mock = $this->mock('MyClass', ['getNumber' => 1]);
  1. Special method this() inside each mock gives you possibility to change non-public properties and call non-public methods of mock via Xpmock\Reflection
$mock = $this->mock('MyClass')->new();
$mock->this()->protectedProperty = 'value';
$mock->this()->protectedMethod();
  1. You can use $this pointer inside your fake methods
$mock = $this->mock('MyClass',
    [
        'property' => 1,
        'getProperty' => function () {
            return $this->property;
        },
    ]
);
  1. It is easy now to create mocks all methods of which return some value, for example null (stub)
$mock = $this->mock('MyClass', null);
  1. Very expected: now it is possible to adjust mocks after creation with magic method mock()
$myClass = $this->mock('MyClass', null);
$myClass->getNumber(); // null
$myClass->mock()
    ->getNumber(1);
$myClass->getNumber(); // 1

ptrofimov/xpmock 适用场景与选型建议

ptrofimov/xpmock 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 483.25k 次下载、GitHub Stars 达 77, 最近一次更新时间为 2013 年 05 月 28 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 ptrofimov/xpmock 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ptrofimov/xpmock 我们能提供哪些服务?
定制开发 / 二次开发

基于 ptrofimov/xpmock 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 483.25k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 78
  • 点击次数: 23
  • 依赖项目数: 170
  • 推荐数: 0

GitHub 信息

  • Stars: 77
  • Watchers: 5
  • Forks: 5
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2013-05-28