<?php use PHPUnit\Framework\TestCase; use DependencyInjector\DI; class DependencyInjectorTest extends TestCase { public function tearDown() { DI::reset(); parent::tearDown(); } /** * Test that the setup works - the class should exist */ public function testSetUp() { self::assertTrue(class_exists('DependencyInjector\DI')); } /** * Test that constructor is not callable */ public function testPrivateConstructor() { $refDI = new ReflectionClass(DI::class); $refConstruct = $refDI->getMethod('__construct'); self::assertTrue($refConstruct->isPrivate()); } /** * Test that DI::get() throws a exception when the requested dependency is unknown. */ public function testGetThrowsForUnknownDependencies() { $this->expectException(DependencyInjector\Exception::class); $this->expectExceptionMessage("Unknown dependency 'unknown'"); DI::get('unknown'); } /** * Test that DI::set() stores something. */ public function testSetStoresSomethingNotCallable() { $something = [$this, 'nonExistingMethod']; DI::set('something', $something); self::assertEquals($something, DI::get('something')); } /** * Test that DI::get() executes the given function and returns the return value. */ public function testGetExecutesAnonymousFunctions() { DI::set('anonymous', function () { return 'fooBar'; }); $result = DI::get('anonymous'); self::assertSame('fooBar', $result); } public function testGetExecutesCallable() { DI::set('getter', [$this, 'getDependencyExample']); $result = DI::get('getter'); self::assertSame('fooBar', $result); } public function getDependencyExample() { return 'fooBar'; } public function testSetStoresValue() { $something = [$this, 'getDependencyExample']; DI::set('array', $something, false, true); $result = DI::get('array'); self::assertSame($something, $result); } /** * Test that the function got not executed before get. */ public function testSetDoesNotExecute() { $calls = 0; DI::set('dontCall', function () use (&$calls) { $calls = $calls + 1; }); self::assertSame(0, $calls); } /** * Test that the function got executed only once. */ public function testGet_executesOnce() { $calls = 0; DI::set('callOnce', function () use (&$calls) { $calls = $calls + 1; return new DateTime(); }); DI::get('callOnce'); DI::get('callOnce'); self::assertSame(1, $calls); } /** * Test that a non singleton got executed for each get. */ public function testGet_executesNonSingleton() { $calls = 0; DI::set('callTwice', function () use (&$calls) { $calls = $calls + 1; return new DateTime(); }, false); DI::get('callTwice'); DI::get('callTwice'); self::assertSame(2, $calls); } /** * Test that DI::set() overrides created instances. */ public function testSet_overridesInstances() { DI::set('microtime', function () { return microtime(true); }); $result1 = DI::get('microtime'); DI::set('microtime', function () { return microtime(true); }); $result2 = DI::get('microtime'); self::assertNotSame($result1, $result2); } /** * Test that you can get instances with magic method. */ public function testGet_callStatic() { DI::set('magicCall', true); /** @noinspection PhpUndefinedMethodInspection */ $result = DI::magicCall(); self::assertTrue($result); } /** * Test that undefined dependencies return the class name if it exists. */ public function testGet_returnsClassName() { $result = DI::get(__CLASS__); } /** * Test that a class name has to be case sensitive. */ public function testGet_classNameIsCaseSensitive() { $this->expectException(DependencyInjector\Exception::class); $this->expectExceptionMessage("Unknown dependency '" . strtolower(__CLASS__) . "'"); $result = DI::get(strtolower(__CLASS__)); self::assertNotSame(strtolower(__CLASS__), $result); } /** * Test that you can override class names. */ public function testGet_returnsStored() { DI::set(__CLASS__, 'FooBar'); $result = DI::get(__CLASS__); self::assertSame('FooBar', $result); } /** * Test that DI::reset() resets the DependencyInjector. */ public function testReset() { DI::set(__CLASS__, function () { return 'FooBar'; }); DI::get(__CLASS__); DI::reset(); self::assertSame(__CLASS__, DI::get(__CLASS__)); } public function testHas() { DI::set('foo', 'bar'); self::assertTrue(DI::has('foo')); } public function testDelete() { DI::set('foo', function () { return 'bar'; }); DI::get('foo'); DI::delete('foo'); self::assertFalse(DI::has('foo')); } }