Search code examples
phpzend-framework2phpspec

Testing objects that are usually generated by factories with phpspec


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!!


Solution

  • 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.