PHPSpec2: A Theologian’s Tool

Lately I wanted to learn PHPSpec2 for real. So I went in to play a little bit with the tool. After reading the documentation some concepts were more clear but others like how to mock or stub were actually worst than when they started.

So I went ahead and stuffed all into my bag for the pilgrimage in a composer.json bag. I know I will probably not need it right away, but hey, better be prepared for the future of the series of this blog post than be found guilty.

{
    "require-dev": {
        "phpspec/phpspec2": "*",
        "behat/behat": "2.4.*@stable",
        "behat/mink": "1.4@stable",
        "behat/mink-extension": "*",
        "behat/mink-goutte-driver": "*",
        "behat/mink-selenium2-driver": "*",
        "behat/common-contexts": "*"
    },
    "config": {
        "bin-dir": "bin"
    },
    "autoload": {"psr-0": {"": "src"}},
    "minimum-stability": "dev"
}

After thinking for a while where could I need the tool, I did not come up with anything better than just trying something that could be otherwise far far from the programming world. Actually my experience tells me programmers are the worst theologians in the world. There, I said it and I vouch it is true, they can’t make good theology. But the tools … ? The tools are the best, here is the proof:

~ bin/phpspec desc Grace
Specification for Grace created in spec/Grace.php.

You are right. I was trying to describe Grace:

~ bin/phpspec run
spec/Grace                                        
   9  ! it should be initializable
      class Grace does not exists.
 
 
             Do you want me to create this class for you?             
                                                               [y/n] y
 
      class Grace has been created.
 
                       100%                        1
 
1 examples (1 broken)
11103ms

First of all, I know 1 is broken and it is me without Grace. 1 Example? Yep, me.

But let’s preserve the full colored experience lest you miss this part:

You guessed right, Grace is not complete because I need a savior. So kept going until I got a better description:

Because I wanted to experiment with mocks I found a very interesting example that made me understood and it was a refreshment to me. I share here the class and its implementation. Check the last method, it uses the docblock notation and it really puts it together for me.

<?php
 
namespace spec;
 
use PHPSpec2\ObjectBehavior;
 
class Grace extends ObjectBehavior
{
    function it_should_be_initializable()
    {
        $this->shouldHaveType('Grace');
    }
 
    function it_should_be_undeserving()
    {
        $this->display()->shouldReturn('forgiveness');
    }
 
    function it_should_befriend_sinners($sinner)
    {
        $this->beFriendOf($sinner)->shouldReturn('yes');
    }
 
    /**
     * @param Justice $justice
     * @param Love $love
     */
    function it_is_costly_but_should_be_free($justice, $love)
    {
        $justice->exercise()->willReturn('Payment required, judgement');
        $love->exercise()->willReturn('Payment made on the cross');
        $this->reconcile($justice, $love)->shouldReturn('Payment required, judgement MEETS Payment made on the cross');
    }
 
    /**
     * @param Sinner $me
     * @param Savior $him
     */
    function it_bears_even_with_my_frailty($me, $him)
    {
        $him->getName()->willReturn('Jesus Christ');
        $me->test()->willReturn('sinned');
        $this->borePowerfullyWithBecause($me, $him)->shouldReturn('He lives!');
    }
}

And here is the Grace class:

<?php
 
class Grace
{
 
    public function display()
    {
        return "forgiveness";
    }
 
    public function beFriendOf($sinner)
    {
        return "yes";
    }
 
    public function reconcile($justice, $love)
    {
        return $justice->exercise()." MEETS ".$love->exercise();
    }
 
    public function borePowerfullyWithBecause($me, $him)
    {
        $answer = 'I mock him too';
 
        if ($me->test() == 'sinned' && $him->getName() == 'Jesus Christ') {
            $answer = 'He lives!';
        }
 
        return $answer;
    }
}

No more phpunit tests, this is the new era of better thought and better theologians hopefully!

Pleas enjoy, tweet and share your knowledge too. I hope to inspect more of the code on the repo of phpspec2 to extract more treasures from it into a blog post soon. Be on the look out until then your young apprentice friend says bye.

6 thoughts on “PHPSpec2: A Theologian’s Tool

  1. $this->beFriendOf($sinner)->shouldReturn(‘yes’);

    method `beFriendOf(…)` of your `Grace` should actually be `isAFriendOf(…)` as it’s a state checker.
    Then, you could just use object-state matcher:

    $this->shouldBeAFriendOf($sinner);

  2. Hi Luis,
    Thanks for the Intro, but am having some issues
    – when i use desc Grace it does create the file in a spec folder which is fine
    – but once i have aded an it_* method to the spec/Grace.php, and i use the run command, it tellsme the class does not exist and it tries to create it,
    which it does successfully but the challenge is thatits not creating the method that the it_* method is maped to.
    – when i try to use the run command again, it tells me that the class does not exist and the tries creating it again.
    Thanks for the help.

    • thanks guys
      i was the one making a mistake
      I guess when i was getting phpspec from composer i didn’t include the
      “autoload”: {“psr-0”: {“”: “src”}},

      Having said that, it seems that the ‘run’ command will still not work until you add a constructor to you class
      Thanks once again

  3. Pingback: Porting your PHPUnit legacy test suite to PhpSpec Adventures: Part VI | Craft It Online!

  4. Pingback: PHPSpec Practices with Symfony2 Controllers: Part VI | Craft It Online!

Leave a Reply to Bba Cancel reply

Your email address will not be published. Required fields are marked *