PHP code example of lucatume / function-mocker

1. Go to this page and download the library: Download lucatume/function-mocker library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

lucatume / function-mocker example snippets




// FunctionMocker needs the functions to be defined to replace them
function get_option($option)
{
    // no-op
}

function update_option($option, $value)
{
    // no-op
}

// The class under test
class Logger
{
    public function log($type, $message)
    {
        $option = get_option('log');
        $option[] = sprintf('[%s] %s - %s', date(DATE_ATOM, time()), $type, $message);
        update_option('log', sprintf('[%s] %s - %s', date(DATE_ATOM, time()), $type, $message));
    }
}

class InternaFunctionReplacementTest extends \PHPUnit\Framework\TestCase
{
    /**
     * It should log the correct message
     * @test
     */
    public function log_the_correct_message()
    {
        $mockTime = time();
        \tad\FunctionMocker\FunctionMocker::replace('time', $mockTime);
        \tad\FunctionMocker\FunctionMocker::replace('get_option', []);
        $update_option = \tad\FunctionMocker\FunctionMocker::replace('update_option');

        $logger = new Logger();

        $logger->log('error', 'There was an error');

        $expected = sprintf('[%s] error - There was an error', date(DATE_ATOM, $mockTime));
        $update_option->wasCalledWithOnce(['log', $expected]);
    }
}


// This is global bootstrap for autoloading
use tad\FunctionMocker\FunctionMocker;


\tad\FunctionMocker\FunctionMocker::init([
    'whitelist' => [dirname(__DIR__) . '/src',dirname(__DIR__) . '/vendor'],
    'blacklist' => [dirname(__DIR__) . '/

class MyTest extends \PHPUnit_Framework_TestCase {
    public function setUp(){
        // before any other set up method
        FunctionMocker::setUp();
        ...
    }

    public function tearDown(){
        ...

        // after any other tear down method
        FunctionMocker::tearDown();
    }
}

FunctionMocker::replace('myFunction', $returnValue);
    
public function testReplacedFunctionReturnsValue(){
    FunctionMocker::replace('myFunction', 23);

    $this->assertEquals(23, myFunction());
}

public fuction testReplacedFunctionReturnsCallback(){
    FunctionMocker::replace('myFunction', function($arg){
            return $arg + 1;
        });

    $this->assertEquals(24, myFunction());
}

public function testReplacedFunctionReturnsValue(){
    FunctionMocker::replaceInOrder('myFunction', [23, 89, 2389]);

    $this->assertEquals(23, myFunction());
    $this->assertEquals(89, myFunction());
    $this->assertEquals(2389, myFunction());
}
  
public function testReplacedFunctionReturnsValue(){
    $myFunction = FunctionMocker::replace('myFunction', 23);

    $this->assertEquals(23, myFunction());

    $myFunction->wasCalledOnce();
    $myFunction->wasCalledWithOnce(23);
}

public function testBatchFunctionReplacement(){
    $functions = ['functionOne', 'functionTwo', 'functionThree', ...];

    FunctionMocker::replace($functions, function($arg){
        return $arg;
        });

    foreach ($functions as $f){
        $this->assertEquals('foo', $f('foo'));
    }
}

public function testBatchFunctionReplacement(){
    $functions = ['functionOne', 'functionTwo', 'functionThree', ...];

    $replacedFunctions = FunctionMocker::replace($functions, function($arg){
        return $arg;
        });
    
    functionOne();

    $functionOne = $replacedFunctions['functionOne'];
    $functionOne->wasCalledOnce();

}

public function testReplacedStaticMethodReturnsValue(){
    FunctionMocker::replace('Post::getContent', 'Lorem ipsum');

    $this->assertEquals('Lorem ipsum', Post::getContent());
}

public function testReplacedStaticMethodReturnsCallback(){
    FunctionMocker::replace('Post::formatTitle', function($string){
        return "foo $string baz";
        });

    $this->assertEquals('foo lorem baz', Post::formatTitle('lorem'));
}

public function testReplacedStaticMethodReturnsValue(){
    $getContent = FunctionMocker::replace('Post::getContent', 'Lorem ipsum');

    $this->assertEquals('Lorem ipsum', Post::getContent());

    $getContent->wasCalledOnce();
    $getContent->wasNotCalledWith('some');
    ...
}

public function testBatchReplaceStaticMethods(){
    $methods = ['Foo::one', 'Foo::two', 'Foo::three'];

    FunctionMocker::replace($methods, 'foo');

    $this->assertEquals('foo', Foo::one());
    $this->assertEquals('foo', Foo::two());
    $this->assertEquals('foo', Foo::three());
}

public function testBatchReplaceStaticMethods(){
    $methods = ['Foo::one', 'Foo::two', 'Foo::three'];

    $replacedMethods = FunctionMocker::replace($methods, 'foo');
    
    Foo::one();

    $one = $replacedMethods['one'];
    $one->wasCalledOnce();
}

// file SomeClass.php

class SomeClass{

    protected $dep;

    public function __construct(Dep $dep){
        $this->dep = $dep;
    }

    public function someMethod(){
        return $this->dep->go();
    }
}

// file SomeClassTest.php   

use tad\FunctionMocker\FunctionMocker;

class SomeClassTest extends PHPUnit_Framework_TestCase {

    /**
     * @test
     */
    public function it_will_call_go(){
        $dep = FunctionMocker::replace('Dep::go', 23);

        $sut = new SomeClass($dep);

        $this->assertEquals(23, $sut->someMethod());
    }
}

$dep->expects($this->any())->method('go')->willReturn(23);

use tad\FunctionMocker\FunctionMocker;

class SomeClassTest extends \PHPUnit_Framework_TestCase {
    
    public function dependencyTest(){

        $func = function($one, $two){
                return $one + $two;
            };

        $mock = FunctionMocker::replace('Dependency')
            ->method('methodOne') // replace with null returning methods
            ->method('methodTwo', 23) // replace the method and return a value
            ->method('methodThree', $func)
            ->get();

        $this->assertNull($mock->methodOne());
        $this->assertEquals(23, $mock->methodTwo());
        $this->assertEquals(4, $mock->methodThree(1,3));

    }
}

class Query {

    ...

    public funtion where($column, $condition, $constraint){
        ...

        return $this;
    }

    public function getResults(){
        return $this->results;
    }

    ...

}

class QueryUser{

    ...

   public function getOne($id){
    $this->query
        ->where('ID', '=', $id)
        ->where('type', '=', $this->type)
        ->getFirst();
   }

   ...

}

public function test_will_call_where_with_proper_args(){
    // tell FunctionMocker to return the mock object itself when
    // the `where` method is called
    FunctionMocker::replace('Query::where', '->');
    $query = FunctionMocker::replace('Query::getFirst', $mockResult);
    $sut = new QueryUser();
    $sut->setQuery($query);
    
    // execute
    $sut->getOne(23);

    // verify
    ...
}

interface SalutingInterface {
    public function sayHi();
}

public function test_say_hi(){
    $mock = FunctionMocker::replace('SalutingInterface::sayHi', 'Hello World!');
    
    // passes
    $this->assertEquals('Hello World!', $mock->sayHi());
}

// file SomeClass.php

class SomeClass{

    public function methodOne(){
        ...
    }

    public function methodTwo(){
        ...
    }
}

// file SomeClassTest.php   

use tad\FunctionMocker\FunctionMocker;

class SomeClassTest extends PHPUnit_Framework_TestCase {

    /**
     * @test
     */
    public function returns_the_same_replacement_object(){
        // replace both class instance methods to return 23
        $replacement = FunctionMocker::replace('SomeClass::methodOne', 23);
        // $replacement === $replacement2
        $replacement2 = FunctionMocker::replace('SomeClass::methodTwo', 23);

        $replacement->methodOne();
        $replacement->methodTwo();

        $replacement->wasCalledOnce('methodOne');
        $replacement->wasCalledOnce('methodTwo');
    }
}

// file SomeClassTest.php   

use tad\FunctionMocker\FunctionMocker;

class SomeClassTest extends PHPUnit_Framework_TestCase {

    /**
     * @test
     */
    public function returns_the_same_replacement_object(){
        // replace both class instance methods to return 23
        $mock = FunctionMocker::replace('SomeClass)
            ->methodOne()
            ->methodTwo();
        $replacement = $mock->get(); // think of $mock->reveal()

        $replacement->methodOne();
        $replacement->methodTwo();

        $mock->verify()->methodOne()->wasCalledOnce();
        $mock->verify()->methodTwo()->wasCalledOnce();
    }
}

public function testBatchInstanceMethodReplacement(){
    $methods = ['SomeClass::methodOne', 'SomeClass::methodTwo'];
    // replace both class instance methods to return 23
    $replacements = FunctionMocker::replace($methods, 23);

    $replacement[0]->methodOne();
    $replacement[1]->methodTwo();

    $replacement[0]->wasCalledOnce('methodOne');
    $replacement[1]->wasCalledOnce('methodTwo');
}
  
// the function should have have been called exactly 2 times
$function->wasCalledTimes(2);

// the function should have been called at least 2 times
$function->wasCalledTimes('>=2');

use tad\FunctionMocker\FunctionMocker as Test;

class SomeTest extends \PHPUnit_Framework_TestCase {

    public function test_true() {
        $this->assertTrue(true);
    }

    public function test_wrapped_true_work_the_same() {
        Test::assertTrue(true);
    }

}
  
public function setUp() {
    FunctionMocker::setTestCase($this);
}
 
FunctionMocker::replaceGlobal('wpdb', 'wpdb::get_row', $rowData);

// this will access $wpdb->get_row()
$post = get_latest_post();

// verify
$this->assertEquals(...);
 
// prepare
$mockWpdb = FunctionMocker::replace('wpdb::get_row', $rowData);
$prevWpdb = isset($GLOBALS['wpdb']) ? $GLOBALS['wpdb'] : null;
$GLOBALS['wpdb'] = $mockWpdb;

// this will access $wpdb->get_row()
$post = get_latest_post();

// verify
$this->assertEquals(...);

// restore state
$GLOBALS['wpdb'] = $prevWpdb;
  
FunctionMocker::setGlobal('switchingToTheme', 'foo');
$do_action = FunctionMocker::replace('do_action');

// exercitate
call_switch_theme_actions();

$do_action->wasCalledWithOnce(['before_switch_to_theme_foo', ])

$prev = isset($GLOBALS['switchingToTheme']) ? $GLOBALS['switchingToTheme'] : null;
$GLOBALS['switchingToTheme'] = 'foo';
$do_action = FunctionMocker::replace('do_action');

// exercitate
call_switch_theme_actions();

// verify 
$do_action->wasCalledWithOnce(['before_switch_to_theme_foo', ])

// restore state
$GLOBALS['switchingToTheme'] = $prev;