phpspec/prophecy

repository·master·Indexed 27 days ago

https://github.com/phpspec/prophecy

A highly opinionated and flexible PHP object mocking framework used for creating dummies, stubs, mocks, and spies. While originally designed for phpspec, it can be integrated into any PHP testing framework, such as PHPUnit. It allows developers to define object behavior using Promises, verify expectations with Predictions, and use Argument tokens for flexible method matching. Requires PHP 7.2.0 or greater.

Tokens
2.1K
Snippets
5
Records
21
Agent score
94%

What's inside Prophecy

  1. Install Prophecy via Composer

    master

    Prophecy requires PHP 7.2.0 or greater. To install it, add phpspec/prophecy to your require-dev section in composer.json and run the composer install command.

    {
        "require-dev": {
            "phpspec/prophecy": "~1.0"
        }
    }
    $> composer install --prefer-dist
  2. Initialize Prophecy and create prophecies

    master

    To use Prophecy, you must first create a Prophet instance. The Prophet is responsible for generating prophecies (instances of ObjectProphecy) which describe the future behavior of objects. You can also specify if the prophesied object should extend a specific class or implement an interface.

    $prophet = new Prophecy\Prophet;
    $prophecy = $prophet->prophesize();
    
    // Specify class hierarchy
    $prophecy->willExtend('stdClass');
    $prophecy->willImplement('SessionHandlerInterface');
  3. Create Dummy objects

    master

    A Dummy is a simple object used to satisfy typehints. It extends or implements the specified classes/interfaces but contains no logic. All public methods return null and no exceptions are thrown. Use $prophecy->reveal() to obtain the dummy object.

    $dummy = $prophecy->reveal();
  4. Use Spies to verify calls

    master

    Prophecy supports spying, which allows you to verify calls after they have occurred without pre-defining predictions. Use the shouldHaveBeenCalled() syntax on the revealed object or the prophecy.

    $em = $prophet->prophesize('Doctrine\ORM\EntityManager');
    $controller->createUser($em->reveal());
    
    // Verify the call happened after the fact
    $em->flush()->shouldHaveBeenCalled();
  5. Create Mock objects with Predictions

    master
    Mocks are doubles used to verify expectations. Unlike stubs, mocks use Predictions to ensure specific methods were called. You must call $prophet->checkPredictions() (typically in a test's tearDown) to trigger the verification of these predictions.
  6. Create Stub objects with Promises

    master
    Stubs are doubles that behave in specific ways when certain methods are called. You define behavior using Promises. A stub will throw an UnexpectedCallException if a method is called that has not been described in the prophecy.
  7. Call original methods on a prophesized class

    master
    Prophecy does not support calling the original methods on a prophesized class. If you need to mock some methods while calling the original implementation of others, it is recommended to refactor the class to adhere to the single-responsibility principle.
  8. Basic usage example with PHPUnit

    master

    To use Prophecy within a PHPUnit test case, initialize a new Prophecy\Prophet instance in your setUp() method and call $this->prophet->checkPredictions() in your tearDown() method to verify expectations. Use $this->prophet->prophesize($className) to create a prophecy, and $prophecy->reveal() to get the actual object to inject into your code.

    <?php
    
    class UserTest extends PHPUnit\Framework\TestCase
    {
        private $prophet;
    
        public function testPasswordHashing()
        {
            $hasher = $this->prophet->prophesize('App\Security\Hasher');
            $user   = new App\Entity\User($hasher->reveal());
    
            $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass');
    
            $user->setPassword('qwerty');
    
            $this->assertEquals('hashed_pass', $user->getPassword());
        }
    
        protected function setUp()
        {
            $this->prophet = new \Prophecy\Prophet;
        }
    
        protected function tearDown()
        {
            $this->prophet->checkPredictions();
        }
    }
  9. Use Argument Wildcards (Tokens)

    master
    Instead of hardcoding exact values in method prophecies, use Prophecy\Argument tokens to match arguments based on type, identity, or custom logic. More precise tokens take precedence over less precise ones.