All Projects → php-mock → Php Mock

php-mock / Php Mock

Licence: wtfpl
Mock built-in PHP functions (e.g. time(), exec() or rand())

Labels

Projects that are alternatives of or similar to Php Mock

DeepfakeHTTP
DeepfakeHTTP is a web server that uses HTTP dumps as a source for responses.
Stars: ✭ 373 (+25.17%)
Mutual labels:  mock
Hippolyte
HTTP Stubbing in Swift
Stars: ✭ 109 (-63.42%)
Mutual labels:  mock
Guzzler
Supercharge your app or SDK with a testing library specifically for Guzzle
Stars: ✭ 272 (-8.72%)
Mutual labels:  mock
mock-req-res
Extensible mock req / res objects for use in unit tests of Express controller and middleware functions.
Stars: ✭ 39 (-86.91%)
Mutual labels:  mock
php-mock-prophecy
Mock built-in PHP functions (e.g. time()) with Prophecy (phpspec).
Stars: ✭ 16 (-94.63%)
Mutual labels:  mock
zmock
zmock--http接口的mock平台
Stars: ✭ 98 (-67.11%)
Mutual labels:  mock
mongo mock go example
How to mock MongoDB in Golang
Stars: ✭ 30 (-89.93%)
Mutual labels:  mock
Mockman
Manage and start the mock servers on your local platform easily
Stars: ✭ 281 (-5.7%)
Mutual labels:  mock
phake
PHP Mocking Framework
Stars: ✭ 464 (+55.7%)
Mutual labels:  mock
Pook
HTTP traffic mocking and testing made simple in Python
Stars: ✭ 257 (-13.76%)
Mutual labels:  mock
egg-datahub
Macaca DataHub plugin for Egg.js
Stars: ✭ 19 (-93.62%)
Mutual labels:  mock
amoss
Amoss - Apex Mock Objects, Spies and Stubs - A Simple Mocking framework for Apex (Salesforce)
Stars: ✭ 55 (-81.54%)
Mutual labels:  mock
falso
All the Fake Data for All Your Real Needs 🙂
Stars: ✭ 877 (+194.3%)
Mutual labels:  mock
mockrequire
Simple module for mocking required dependencies. Works with any testing suite.
Stars: ✭ 17 (-94.3%)
Mutual labels:  mock
Rewire
Easy monkey-patching for node.js unit tests
Stars: ✭ 2,940 (+886.58%)
Mutual labels:  mock
smart-cloud
基于springboot && springcloud的脚手架,支持服务合并部署与拆分部署、接口加解密签名、日志数据 脱敏、接口数据mock、接口文档自动生成、请求幂等校验、接口日志&&sql日志切面打印、分表分库分布式事务、国际化语言等
Stars: ✭ 167 (-43.96%)
Mutual labels:  mock
mokker
The mock does not mock you. The video: https://www.youtube.com/watch?v=gGLNJpC-Ov0
Stars: ✭ 13 (-95.64%)
Mutual labels:  mock
Hammox
🏝 automated contract testing via type checking for Elixir functions and mocks
Stars: ✭ 289 (-3.02%)
Mutual labels:  mock
Dva Admin
dva admin antd dashboard
Stars: ✭ 278 (-6.71%)
Mutual labels:  mock
Fflib Apex Mocks
An Apex mocking framework for true unit testing in Salesforce, with Stub API support
Stars: ✭ 253 (-15.1%)
Mutual labels:  mock

PHP-Mock: mocking built-in PHP functions

PHP-Mock is a testing library which mocks non deterministic built-in PHP functions like time() or rand(). This is achieved by PHP's namespace fallback policy:

PHP will fall back to global functions […] if a namespaced function […] does not exist.

PHP-Mock uses that feature by providing the namespaced function. I.e. you have to be in a non global namespace context and call the function unqualified:

namespace foo;

$time = time(); // This call can be mocked, a call to \time() can't.

Requirements and restrictions

  • Only unqualified function calls in a namespace context can be mocked. E.g. a call for time() in the namespace foo is mockable, a call for \time() is not.

  • The mock has to be defined before the first call to the unqualified function in the tested class. This is documented in Bug #68541. In most cases, you can ignore this restriction but if you happen to run into this issue you can call Mock::define() before that first call. This would define a side effectless namespaced function which can be enabled later. Another effective approach is running your test in an isolated process.

Alternatives

If you can't rely on or just don't want to use the namespace fallback policy, there are alternative techniques to mock built-in PHP functions:

  • PHPBuiltinMock relies on the APD extension.

  • MockFunction is a PHPUnit extension. It uses the runkit extension.

  • UOPZ is a Zend extension which allows, among others, renaming and deletion of functions.

  • vfsStream is a stream wrapper for a virtual file system. This will help you write tests which covers PHP stream functions (e.g. fread() or readdir()).

Installation

Use Composer:

composer require --dev php-mock/php-mock

Usage

You don't need to learn yet another API. PHP-Mock has integrations for these testing frameworks:

Note: If you plan to use one of the above mentioned testing frameworks you can skip reading any further and just go to the particular integration project.

PHP-Mock API

You find the API in the namespace phpmock.

Create a Mock object. You can do this with the fluent API of MockBuilder:

After you have build your Mock object you have to call enable() to enable the mock in the given namespace. When you are finished with that mock you should disable it by calling disable() on the mock instance.

This example illustrates mocking of the unqualified function time() in the namespace foo:

namespace foo;

use phpmock\MockBuilder;

$builder = new MockBuilder();
$builder->setNamespace(__NAMESPACE__)
        ->setName("time")
        ->setFunction(
            function () {
                return 1417011228;
            }
        );
                    
$mock = $builder->build();

// The mock is not enabled yet.
assert (time() != 1417011228);

$mock->enable();
assert (time() == 1417011228);

// The mock is disabled and PHP's built-in time() is called.
$mock->disable();
assert (time() != 1417011228);

Instead of setting the mock function with MockBuilder::setFunction() you could also use the existing FixedValueFunction:

namespace foo;

use phpmock\MockBuilder;
use phpmock\functions\FixedValueFunction;

$builder = new MockBuilder();
$builder->setNamespace(__NAMESPACE__)
        ->setName("time")
        ->setFunctionProvider(new FixedValueFunction(1417011228));

$mock = $builder->build();

Reset global state

An enabled mock changes global state. This will break subsequent tests if they run code which would call the mock unintentionally. Therefore you should always disable a mock after the test case. You will have to disable the created mock. You could do this for all mocks by calling the static method Mock::disableAll().

Mock environments

Complex mock environments of several mocked functions can be grouped in a MockEnvironment:

SleepEnvironmentBuilder

The SleepEnvironmentBuilder builds a mock environment where sleep() and usleep() return immediatly. Furthermore they increase the amount of time in the mocked date(), time() and microtime():

namespace foo;

use phpmock\environment\SleepEnvironmentBuilder;

$builder = new SleepEnvironmentBuilder();
$builder->addNamespace(__NAMESPACE__)
        ->setTimestamp(1417011228);

$environment = $builder->build();
$environment->enable();

// This won't delay the test for 10 seconds, but increase time().        
sleep(10);

assert(1417011228 + 10 == time());

If the mocked functions should be in different namespaces you can add more namespaces with SleepEnvironmentBuilder::addNamespace()

Spies

A Spy gives you access to the function invocations. Spy::getInvocations() gives you access to the arguments and return value.

As a Spy is a specialization of Mock it behaves identically. However you could ommit the third constructor parameter callable $function which would then create a spy using the existing function. E.g. a new Spy(__NAMESPACE__ , "rand") would create a spy which basically proxies PHP's built-in rand():

namespace foo;

use phpmock\spy\Spy;

function bar($min, $max) {
    return rand($min, $max) + 3;
}

$spy = new Spy(__NAMESPACE__, "rand");
$spy->enable();

$result = bar(1, 2);

assert ([1, 2]  == $spy->getInvocations()[0]->getArguments());
assert ($result == $spy->getInvocations()[0]->getReturn() + 3);

License and authors

This project is free and under the WTFPL. Responsable for this project is Markus Malkusch [email protected]. This library was inspired by Fabian Schmengler's article PHP: “Mocking” built-in functions like time() in Unit Tests.

Donations

If you like PHP-Mock and feel generous donate a few Bitcoins here: 1335STSwu9hST4vcMRppEPgENMHD2r1REK

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].