1

When testing with PHPSpec how can I use class interfaces injected into my methods rather then the actual concrete class?

For example I have a Product class that injects a VariationInterface into a method:

/**
 * ...
 */
public function addVarient(VarientInterface $varient)
{
    return $this->varients->add($varient);
}

Although since PHPSpec has no IOC container to bind VarientInterface to Varient I cant really test my classes.

Is it not best practice to code to an interface and not a concrete class?

AndrewMcLagan
  • 13,459
  • 23
  • 91
  • 158
  • You should code against an interface, not a concrete class. However, that's not you do in your example. As the "add" method doesn't exist on the interface, you're actually coding against an implementation. Also answered on the phpspec issue tracker: https://github.com/phpspec/phpspec/issues/584#issuecomment-67090359 – Jakub Zalas Dec 17 '14 at 23:14

1 Answers1

1

You can mock concrete classes and intefaces in PHPSpec.

Please verify this example:

<?php

//file spec/YourNameSpace/ProductSpec.php

namespace spec\YourNameSpace\Product;

use YourNameSpace\VarientInterface;
use PhpSpec\ObjectBehavior;

class ProductSpec extends ObjectBehavior
{
    function it_is_varients_container(VarientInterface $varient)
    {
        $this->addVarient($varient);

        $this->getVarients()->shouldBe([$varient]);
    }
}

You just pass VarientInterface as parameter to test method. This VarientInterface is mocked underneath by PhpSpec (really by Prophecy).

Please check offical phpspec documentaion about mocking http://www.phpspec.net/docs/introduction.html#prophet-objects

l3l0
  • 3,363
  • 20
  • 19