Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ZF2 service locator & dependency injection

The good people at Zend, and a number of bloggers, are recommending the new service locator/manager for ZF2, rather than its inbuilt Dependency Injection system.

My question is, is it possible/convenient to inject mock objects into a service? I have seen some slightly clumsy attempts to do this in the PHPUnit bootstrap of a module; but is there a way of using this service system that is as clean and convenient as, say, ZF1 + Yadif?

like image 561
AgileTillIDie Avatar asked Feb 06 '13 16:02

AgileTillIDie


1 Answers

Yes, you can inject mock objects into a service. For an unit test, the service locator does not even come into play:

$service = new MyService($mockDependency);

If you are writing complex integration tests where you need to use the Service Locator to be configured with a graph of dependencies and mocks, you can setup something like what I am doing with my modules:

$serviceLocator   = ServiceManagerFactory::getServiceManager(); // see comment below
$dbConnectionMock = $this->getMock('My\Db\Connection');

$serviceLocator->setAllowOverride(true);
// replacing connection service with our fake one
$serviceLocator->setService('connection_service_name', $dbConnectionMock);

$service = $serviceLocator->get('service_that_uses_a_connection');

You can find an example of ServiceManagerFactory in DoctrineORMModule at https://github.com/doctrine/DoctrineORMModule/blob/0.7.0/tests/DoctrineORMModuleTest/Util/ServiceManagerFactory.php

This works assuming that service_that_uses_a_connection is instantiated by a factory that injects connection_service_name into it.

You can still use also Zend\Di if you prefer to, but it's not really needed in such cases.

like image 65
Ocramius Avatar answered Nov 02 '22 18:11

Ocramius