unit-testingcakephpcakephp-3.3

Is it possible to use IntegrationTestCase to assertEventFired?


I'm firing an event from my controller and I want to assert that it is fired in the IntegrationTestCase. I tried using the assertEventFired() method but I get an error:

The event manager you are asserting against is not configured to track events.

I don't see how I can get an instance of the controller to do $controller->eventManager()->setEventList(new EventList()); to enable event tracking.

Is it possible to do this with IntegrationTestCase or do I need to build the controller manually as its done in the core test suite for Cake\Controller\Controller?

cakephp 3.3.15


Solution

  • You can gain access to the controller in an overriden IntegrationTestCase::controllerSpy() method, and after the request has been dispatched, the controller will be available via $this->_controller in your test method too.

    public function controllerSpy($event, $controller = null)
    {
        parent::controllerSpy($event, $controller);
    
        if (isset($this->_controller)) {
            $eventList = new \Cake\Event\EventList();
            $this->_controller->eventManager()->setEventList($eventList);
        }
    }
    
    public function someTest()
    {
        // ...
    
        $this->assertEventFired('someEvent', $this->_controller->eventManager());
    }
    

    You could possibly also rely on the global event manager, given that there should be only one controller per request.

    That however would also require that the event names are unique, as it's not possible to further restrict the origin of the event using assertEventFired(), so that's not an overly good solution. However, for the sake of completion, here's an example for that too.

    public function someTest()
    {
        $eventList = new \Cake\Event\EventList();
        \Cake\Event\EventManager::instance()->setEventList($eventList);
    
        // ...
    
        $this->assertEventFired('someEvent');
    }
    

    See also