定制 jeremeamia/func-mocker 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

jeremeamia/func-mocker

Composer 安装命令:

composer require --dev jeremeamia/func-mocker

包简介

Allows you to overwrite global function used within a namespace for the purposes of testing.

README 文档

README

FuncMocker – Mocking PHP functions like a... punk rocker?

Latest Version on Packagist Software License Build Status Total Downloads

Allows you to overwrite (i.e., mock) global functions used within a given namespace for the purposes of testing.

There are two main use cases I developed this for:

  1. When you are testing objects that call non-deterministic functions like time() and rand(), and you need these functions to return deterministic values for the sake of the test.
  2. When you are working with code where you have objects that must make calls to functions. This is pretty common in legacy codebases that were not previously object-oriented in nature. For example, if you're project has a function called db_add() that you end up using in an object in your model layer, you might want to "mock" that function when you are testing so you don't actually make calls to the database in your unit tests.

The simple technique behind this code is described in this blog post by Fabian Schmengler. Basically, it involves taking advantage of PHP's namespace resolution rules.

Install

Via Composer

$ composer require jeremeamia/func-mocker

Usage

Let's you have a RandomNumberGenerator class in the namespace, My\App, that calls the global function rand(). You could overwrite the usage of rand() for that particular namespace by using FuncMocker.

use My\App\RandomNumberGenerator;
use FuncMocker\Mocker;

Mocker::mock('rand', 'My\App', function () {
    return 5;
});

$rng = new RandomNumberGenerator(1, 10);
echo $rng->getNumber();
//> 5
echo $rng->getNumber();
//> 5
echo $rng->getNumber();
//> 5

Longer Example

Assume there is a class that uses the global function (e.g., time()) that you'd like to mock.

<?php

namespace My\Crypto;

use Psr\Http\Message\RequestInterface as Request;

class Signer
{
    // ...

    public function getStringToSign(Request $request)
    {
        return $request->getMethod() . "\n"
            . time() . "\n"
            . $request->getHeader('X-API-Operation')[0] . "\n"
            . $request->getBody();            
    }
    
    // ...
}

Here is an example of a PHPUnit test that uses FuncMocker to mock time() to return a fixed value, making it much easier to write a test.

<?php

namespace My\App\Tests;

use FuncMocker\Mocker as FuncMocker;
use My\Crypto\Signer;
use Psr\Http\Message\RequestInterface as Request;

class SignerTest extends \PHPUnit_Framework_TestCase
{
    // ...

    public function testCanGetStringToSign()
    {
        // Mock the request with PHPUnit
        $request = $this->getMock(Request::class);
        $request->method('getMethod')->willReturn('POST');
        $request->method('getHeader')->willReturn(['CREATE_THING']);
        $request->method('getBody')->willReturn('PARAMS');
        
        // Mock the call to PHP's time() function to give us a deterministic value.
        FuncMocker::mock('time', 'My\Crypto', function () {
            return 12345;
        });
                
        $signer = new Signer();
        
        // Check to see that the string to sign is constructed how we would expect.
        $this->assertEquals(
            "POST\n12345\nCREATE_THING\nPARAMS",
            $signer->getStringToSign()
        );
    }
    
    // ...
}

Disabling and Re-Enabling

FuncMocker also lets you disable mocks you've setup, in case you need the function to behave normally in your some of your tests.

$func = FuncMocker\Mocker::mock('time()', 'My\App', function () {
    return 1234567890;
});

echo My\App\time();
//> 1234567890

$func->disable();
echo My\App\time();
//> 1458018866

$func->enable();
echo My\App\time();
// > 1234567890

Limitations

  1. The function to be mocked must be used in a namespace other than the global namespace.
  2. The function to be mocked must not be referenced using a fully-qualified name (e.g., \time()).

Testing

$ composer test

Credits

Alternatives

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 22
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 19
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 19
  • Watchers: 3
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-03-15

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固