0

Exist some class:

class A{
  protected $options;
  public function setDefaults($defaults){
      $this->options=$defaults;
  }
  public function getOptions(){
     return  $this->options;
  }
}

And other class:

class B{
public function setDefaultOptions(A $options){
   $options->setDefaults('foo'=>'bar')
}

}

Uses:

$a=new A();
$b=new B();
$b->setDefaultsOptions(a);

How I can check in spec for B that $a->options['foo'] is set?


Now I implement it as:

  public function getMatchers(){
    return array('haveResolverKey'=>
    function($subject, $key){
        $resolver=new A();
        $subject->setDefaultOptions($resolver);
        $ret=$resolver->getOptions();

        return isset($ret[$key]);
    });
  }

Maybe exist easy way?

nonlux
  • 774
  • 2
  • 6
  • 20

1 Answers1

1

How I can check in spec for B that $a->options['foo'] is set?

You shouldn't. Verify the behaviour instead of a state.

In other words you should verify outputs of methods and express expectations against collaborators, instead of verifying the internal state of your classes.

Internals might change once you refactor, behaviour should remain the same.

As far as I understood your example, it could be described as:

class BSpec extends ObjectBehavior
{
    function it_sets_defaults_on_a(A $a)
    {
        $a->setDefaults(array('foo' => 'bar'))->shouldBeCalled();

        $this->setDefaultOptions($a);
    }
}
Jakub Zalas
  • 35,761
  • 9
  • 93
  • 125
  • OK. But I want to specing some code rule. As setting ['intention' in Symfony 2 Form Type](http://php-and-symfony.matthiasnoback.nl/2013/02/symfony2-security-enhancements-part-i/). phpspec is not true tool for solving this problem? – nonlux Nov 08 '13 at 09:36
  • What is your code rule? What do you mean by "setting injection"? – Jakub Zalas Nov 08 '13 at 15:12
  • Not setting injection, but 'intention'. Symfony form suggest define addition settings for generation csrf token. I want to check if I forgot to set this parameter. – nonlux Nov 09 '13 at 08:11
  • PhpSpec helps you with a design. You should check for behaviour and not state. As far as I understood what you're trying to do - to verify that while calling B.setDefaultOptions(A), A.setOptions() will be called - I gave the right answer. – Jakub Zalas Nov 09 '13 at 21:57
  • Thank. Talks with you and Marcello Duarte forced me to reconsider the approach to specifications. But I found little information about the practices of use BDDSpecs. – nonlux Nov 10 '13 at 04:04
  • This not only applies to PhpSpec. It's just that PhpSpec forces you to do it right whenever possible, while PhpUnit will let you do the wrong thing. – Jakub Zalas Nov 10 '13 at 15:43