Spy Test Double Using Prophecy

Spy is a test double which records its actions. After code execution you can check if interaction is as expected. You use it to make sure the method(s) was called.

Below is the class which has an optional dependency which is called:

<?php

namespace App;

class Questioner
{
    private $output;
    private $questions = [];
    private $scorer;

    public function __construct(OutputInterface $output, ScorerInterface $scorer = null)
    {
        $this->output = $output;
        $this->scorer = $scorer;
    }

    /** @return int */
    public function getQuestionsCount()
    {
        return 0;
    }

    /**
     * Save under a new name.
     *
     * @param  string $name
     * @return boolean
     */
    public function saveAs($name)
    {
        $saved = $this->output->save($this->questions, $name);

        if ($saved && $this->scorer) {
            $this->scorer->update();
        }

        return $saved;
    }
}

To check that the update() method on Scorer is called use the following spy test double:

<?php

namespace tests;

use App\Output;
use App\Questioner;
use App\Scorer;
use Prophecy\Argument;

class QuestionerTest extends \PHPUnit_Framework_TestCase
{
    // ...

    /**
     * @test
     */
    function score_is_updated_on_save()
    {
        $outputStub = $this->prophesize(Output::CLASS);
        $outputStub->save([], Argument::type('string'))->willReturn(true);
        $scorerSpy = $this->prophesize(Scorer::CLASS);
        $questioner = new Questioner($outputStub->reveal(), $scorerSpy->reveal());

        $questioner->saveAs('any name');

        $scorerSpy->update()->shouldHaveBeenCalled();
    }
}

This article is from the Test doubles using Prophecy series which is made from following articles:

  • Dummy Test Double Using Prophecy
  • Stub Test Double Using Prophecy
  • Spy Test Double Using Prophecy
  • Mock Test Double Using Prophecy
  • Fake Test Double Using Prophecy
  • Posted in: PHP, Prophecy, TDD, Technical

    Comments