Welcome to Abdul Malik Ikhsan's Blog

Testing “expects($this->any())” with Prophecy with Spying

Posted in Tutorial PHP by samsonasik on September 27, 2015

Testing method call from Collaborator that may be 0 or any other count with phpunit Framework test case can be done with expects($this->any()) from mock object. If we are using Prophecy for mocking tools, it can be done with spying.
However, the spying itself need checks whenever method is called or not. We need findProphecyMethodCalls() call againsts ObjectProphecy for that.

For example, we have a class with collaborator like the following:

namespace App;

class Awesome
    private $awesomeDependency;

    public function __construct(AwesomeDependency $awesomeDependency)
        $this->awesomeDependency = $awesomeDependency;

    public function process($data)
        $rand = rand(1, 2);
        if ($rand === 1) {
            return $this->awesomeDependency->process($data);
        return $data;

The rand() usage is just a sample, in real app, we may have a heavy logic and it may fall to not call the collaborator.

The tests can be done like this:

namespace AppTest;

use App\Awesome;
use App\AwesomeDependency;
use PHPUnit_Framework_TestCase;
use Prophecy\Argument;
use Prophecy\Argument\ArgumentsWildcard;

class AwesomeTest extends PHPUnit_Framework_TestCase
    protected function setUp()
        $this->awesomeDependency = $this->prophesize(AwesomeDependency::class);
        $this->awesome     = new Awesome($this->awesomeDependency->reveal());

    public function testProcess()
        $data = [
            'foo' => 'abcdef',

        // make \Prophecy\MethodProphecy instance
        $methodProphecy = $this->awesomeDependency
        // call method from actual instance

        $calls = $this->awesomeDependency->findProphecyMethodCalls(
            new ArgumentsWildcard([$data])
        $count = count($calls);
        // assert how many times it called 
        if ($count) {
            // echoing just to prove
            echo 'Method from collaborator has been called';
        } else {
            // echoing just to prove
            echo 'Method from collaborator has not been called';

Of course, it may be can’t be called ‘expecting’ before for something has done, it may be can be called as ‘recording’ what already happen, but by this usage, we can prove if it actually called in actual code.