TestCase.php 2.37 KB
<?php

namespace FootyRoom\Tests;

use Illuminate\Events\Dispatcher;
use PHPUnit\Framework\MockObject\MockObject;
use FootyRoom\Providers\EventServiceProvider;
use AlbertCht\Lumen\Testing\TestCase as AlbertChtTestCase;

abstract class TestCase extends AlbertChtTestCase
{
    /**
     * Creates the application.
     *
     * @return \Laravel\Lumen\Application
     */
    public function createApplication()
    {
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->make('url')->forceRootUrl(
            'http://'.$app->make(\FootyRoom\Config::class)->get('domain')
        );

        return $app;
    }

    public function setUp()
    {
        parent::setUp();

        $uses = array_flip(class_uses_recursive(get_class($this)));

        if (isset($uses[SetsUpFixtures::class])) {
            $this->setUpFixtures();
        }
    }

    /**
     * Tests that a specified listener in app's EventServiceProvider is called.
     */
    protected function expectListenerCalled(string $listener): MockObject
    {
        [$class, $method] = explode('@', $listener);
        $method = $method ?: 'handle';

        $instance = $this->getMockBuilder($class)
            ->setMethods([$method])
            ->disableOriginalConstructor()
            ->getMock();

        $instance->expects($this->once())->method($method);

        $this->app->instance($class, $instance);

        // Create a new dispatcher that will register only one listener that we are interested in.
        $dispatcher = new class(app()) extends Dispatcher {
            public function listen($events, $listener)
            {
                if ($listener === $this->expectedListener) {
                    parent::listen($events, $listener);
                }
            }
        };

        $dispatcher->expectedListener = $listener;

        $this->app->instance('events', $dispatcher);

        // Register all listeners again, because we replaced dispatcher with new empty instance.
        (new EventServiceProvider($this->app))->boot();

        return $instance;
    }

    public function assertArrayHaveKeys(array $keys, $data)
    {
        foreach($keys as $key){
            $this->assertArrayHasKey($key, $data);
        }
    }

    public function assertObjectHaveAttributes(array $keys, $data)
    {
        foreach($keys as $key){
            $this->assertObjectHasAttribute($key, $data);
        }
    }
}