4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\DependencyInjection\Tests;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\DependencyInjection\Container;
16 use Symfony\Component\DependencyInjection\ServiceLocator;
17 use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
19 class ServiceLocatorTest extends TestCase
21 public function testHas()
23 $locator = new ServiceLocator(array(
24 'foo' => function () { return 'bar'; },
25 'bar' => function () { return 'baz'; },
26 function () { return 'dummy'; },
29 $this->assertTrue($locator->has('foo'));
30 $this->assertTrue($locator->has('bar'));
31 $this->assertFalse($locator->has('dummy'));
34 public function testGet()
36 $locator = new ServiceLocator(array(
37 'foo' => function () { return 'bar'; },
38 'bar' => function () { return 'baz'; },
41 $this->assertSame('bar', $locator->get('foo'));
42 $this->assertSame('baz', $locator->get('bar'));
45 public function testGetDoesNotMemoize()
48 $locator = new ServiceLocator(array(
49 'foo' => function () use (&$i) {
56 $this->assertSame('bar', $locator->get('foo'));
57 $this->assertSame('bar', $locator->get('foo'));
58 $this->assertSame(2, $i);
62 * @expectedException \Psr\Container\NotFoundExceptionInterface
63 * @expectedExceptionMessage Service "dummy" not found: the container inside "Symfony\Component\DependencyInjection\Tests\ServiceLocatorTest" is a smaller service locator that only knows about the "foo" and "bar" services.
65 public function testGetThrowsOnUndefinedService()
67 $locator = new ServiceLocator(array(
68 'foo' => function () { return 'bar'; },
69 'bar' => function () { return 'baz'; },
72 $locator->get('dummy');
76 * @expectedException \Psr\Container\NotFoundExceptionInterface
77 * @expectedExceptionMessage The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.
79 public function testThrowsOnUndefinedInternalService()
81 $locator = new ServiceLocator(array(
82 'foo' => function () use (&$locator) { return $locator->get('bar'); },
89 * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
90 * @expectedExceptionMessage Circular reference detected for service "bar", path: "bar -> baz -> bar".
92 public function testThrowsOnCircularReference()
94 $locator = new ServiceLocator(array(
95 'foo' => function () use (&$locator) { return $locator->get('bar'); },
96 'bar' => function () use (&$locator) { return $locator->get('baz'); },
97 'baz' => function () use (&$locator) { return $locator->get('bar'); },
100 $locator->get('foo');
104 * @expectedException \Psr\Container\NotFoundExceptionInterface
105 * @expectedExceptionMessage Service "foo" not found: even though it exists in the app's container, the container inside "caller" is a smaller service locator that only knows about the "bar" service. Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "SomeServiceSubscriber::getSubscribedServices()".
107 public function testThrowsInServiceSubscriber()
109 $container = new Container();
110 $container->set('foo', new \stdClass());
111 $subscriber = new SomeServiceSubscriber();
112 $subscriber->container = new ServiceLocator(array('bar' => function () {}));
113 $subscriber->container = $subscriber->container->withContext('caller', $container);
115 $subscriber->getFoo();
118 public function testInvoke()
120 $locator = new ServiceLocator(array(
121 'foo' => function () { return 'bar'; },
122 'bar' => function () { return 'baz'; },
125 $this->assertSame('bar', $locator('foo'));
126 $this->assertSame('baz', $locator('bar'));
127 $this->assertNull($locator('dummy'), '->__invoke() should return null on invalid service');
131 class SomeServiceSubscriber implements ServiceSubscriberinterface
135 public function getFoo()
137 return $this->container->get('foo');
140 public static function getSubscribedServices()
142 return array('bar' => 'stdClass');