Skip to content
Snippets Groups Projects
DependencyInjectorTest.php 5.36 KiB
Newer Older
Thomas Flori's avatar
Thomas Flori committed
<?php

use PHPUnit\Framework\TestCase;
use DependencyInjector\DI;
Thomas Flori's avatar
Thomas Flori committed

class DependencyInjectorTest extends TestCase
{
    public function tearDown()
    {
Thomas Flori's avatar
Thomas Flori committed
        DI::reset();
        parent::tearDown();
    }

    /**
     * Test that the setup works - the class should exist
     */
    public function testSetUp()
    {
Thomas Flori's avatar
Thomas Flori committed
        self::assertTrue(class_exists('DependencyInjector\DI'));
Thomas Flori's avatar
Thomas Flori committed
    }
Thomas Flori's avatar
Thomas Flori committed
    /**
     * Test that constructor is not callable
     */
    public function testPrivateConstructor()
    {
        $refDI        = new ReflectionClass(DI::class);
Thomas Flori's avatar
Thomas Flori committed
        $refConstruct = $refDI->getMethod('__construct');

Thomas Flori's avatar
Thomas Flori committed
        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');
    }
Thomas Flori's avatar
Thomas Flori committed

    /**
     * Test that DI::set() stores something.
     */
    public function testSetStoresSomethingNotCallable()
    {
        $something = [$this, 'nonExistingMethod'];
Thomas Flori's avatar
Thomas Flori committed

        DI::set('something', $something);

Thomas Flori's avatar
Thomas Flori committed
        self::assertEquals($something, DI::get('something'));
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that DI::get() executes the given function and returns the return value.
     */
    public function testGetExecutesAnonymousFunctions()
    {
        DI::set('anonymous', function () {
Thomas Flori's avatar
Thomas Flori committed
            return 'fooBar';
        });

        $result = DI::get('anonymous');

Thomas Flori's avatar
Thomas Flori committed
        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';
    }

Thomas Flori's avatar
Thomas Flori committed
    public function testSetStoresValue()
    {
        $something = [$this, 'getDependencyExample'];
        DI::set('array', $something, false, true);

        $result = DI::get('array');

        self::assertSame($something, $result);
    }

Thomas Flori's avatar
Thomas Flori committed
    /**
     * Test that the function got not executed before get.
     */
    public function testSetDoesNotExecute()
    {
Thomas Flori's avatar
Thomas Flori committed
        $calls = 0;

        DI::set('dontCall', function () use (&$calls) {
Thomas Flori's avatar
Thomas Flori committed
            $calls = $calls + 1;
        });

Thomas Flori's avatar
Thomas Flori committed
        self::assertSame(0, $calls);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that the function got executed only once.
     */
    public function testGet_executesOnce()
    {
Thomas Flori's avatar
Thomas Flori committed
        $calls = 0;
        DI::set('callOnce', function () use (&$calls) {
Thomas Flori's avatar
Thomas Flori committed
            $calls = $calls + 1;
            return new DateTime();
        });

        DI::get('callOnce');
        DI::get('callOnce');

Thomas Flori's avatar
Thomas Flori committed
        self::assertSame(1, $calls);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that a non singleton got executed for each get.
     */
    public function testGet_executesNonSingleton()
    {
Thomas Flori's avatar
Thomas Flori committed
        $calls = 0;
        DI::set('callTwice', function () use (&$calls) {
Thomas Flori's avatar
Thomas Flori committed
            $calls = $calls + 1;
            return new DateTime();
        }, false);

        DI::get('callTwice');
        DI::get('callTwice');

Thomas Flori's avatar
Thomas Flori committed
        self::assertSame(2, $calls);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that DI::set() overrides created instances.
     */
    public function testSet_overridesInstances()
    {
        DI::set('microtime', function () {
Thomas Flori's avatar
Thomas Flori committed
            return microtime(true);
        });
        $result1 = DI::get('microtime');

        DI::set('microtime', function () {
Thomas Flori's avatar
Thomas Flori committed
            return microtime(true);
        });
        $result2 = DI::get('microtime');

Thomas Flori's avatar
Thomas Flori committed
        self::assertNotSame($result1, $result2);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that you can get instances with magic method.
     */
    public function testGet_callStatic()
    {
Thomas Flori's avatar
Thomas Flori committed
        DI::set('magicCall', true);

        /** @noinspection PhpUndefinedMethodInspection */
        $result = DI::magicCall();

Thomas Flori's avatar
Thomas Flori committed
        self::assertTrue($result);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that undefined dependencies return the class name if it exists.
     */
    public function testGet_returnsClassName()
    {
Thomas Flori's avatar
Thomas Flori committed
        $result = DI::get(__CLASS__);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that a class name has to be case sensitive.
     */
    public function testGet_classNameIsCaseSensitive()
    {
Thomas Flori's avatar
Thomas Flori committed
        $this->expectException(DependencyInjector\Exception::class);
        $this->expectExceptionMessage("Unknown dependency '" . strtolower(__CLASS__) . "'");

        $result = DI::get(strtolower(__CLASS__));
Thomas Flori's avatar
Thomas Flori committed
        self::assertNotSame(strtolower(__CLASS__), $result);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that you can override class names.
     */
    public function testGet_returnsStored()
    {
Thomas Flori's avatar
Thomas Flori committed
        DI::set(__CLASS__, 'FooBar');

        $result = DI::get(__CLASS__);

Thomas Flori's avatar
Thomas Flori committed
        self::assertSame('FooBar', $result);
Thomas Flori's avatar
Thomas Flori committed
    }

    /**
     * Test that DI::reset() resets the DependencyInjector.
     */
    public function testReset()
    {
        DI::set(__CLASS__, function () {
Thomas Flori's avatar
Thomas Flori committed
            return 'FooBar';
        });
        DI::get(__CLASS__);

        DI::reset();

Thomas Flori's avatar
Thomas Flori committed
        self::assertSame(__CLASS__, DI::get(__CLASS__));
    }

    public function testHas()
    {
Thomas Flori's avatar
Thomas Flori committed
        DI::set('foo', 'bar');

        self::assertTrue(DI::has('foo'));
    }

    public function testDelete()
    {
        DI::set('foo', function () {
            return 'bar';
        });
        DI::get('foo');
Thomas Flori's avatar
Thomas Flori committed

        DI::delete('foo');
Thomas Flori's avatar
Thomas Flori committed

        self::assertFalse(DI::has('foo'));
Thomas Flori's avatar
Thomas Flori committed
    }
Thomas Flori's avatar
Thomas Flori committed
}