0

How do you go about implementing tests that can leverage your factories to create your test objects?

For example, imagine you have a Zend Framework 2 factory like so:

class FooServiceFactory implements FactoryInterface{

    public function createService( ServiceLocatorInterface $serviceLocator ){

        $bar = new Bar($serviceLocator->get('config'));
        return new FooService( $bar );
    }
}

I could easily modify my FooServiceSpec's let function to look like this (using my ZF2 phpspec extension to get the SM):

function let(){
    $bar = new Bar($this->getServiceLocator()->get('config'));
    $this->beConstructedWith( $bar );
}

In doing so, however, I am not testing my factories. I could of course write separate tests to test the factories themselves, but it's a duplicated effort.

Is there a means to completely defer object instantiation to a custom routine? That way in my test, I could do (fictitious):

function letBetter(){
    return $this->getServiceLocator()->get(FooService::class);
}

Trying avoid duplication!

Thanks!!

Saeven
  • 2,280
  • 1
  • 20
  • 33

1 Answers1

2

If you are testing your FooService object, you should only test the FooService object and mock everything else (you shouldn't use any service locator unit in the spec):

class FooServiceSpec extends ObjectBehaviour
{
    function let(Bar $bar)
    {
        $this->beConstructedWith($bar);
    }

    function it_xxx()
    {
        // ...
    }
}

If you want to test the factory, test the factory only and not the service locator or FooService.

Wouter J
  • 41,455
  • 15
  • 107
  • 112
  • 1
    Furthermore, you should write a separate integration test for your factory to make sure that it actually does what it promises and creates a FooService. You wouldn't use phpspec for this, but for example phpunit. – Jakub Zalas Jan 23 '16 at 12:47