Я разрабатываю приложение с Zend Framework 2. Некоторые сервисы приложений уведомляют заинтересованных слушателей, которые запускают некоторые методы в других сервисах, например:
UserService
<?php
class UserService implements EventManagerAwareInterface
{
public function create($data = array())
{
// user is already created here
$params = array("user" => $user);
$this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, $params);
}
}
UserListener
<?php
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserListener implements ListenerAggregateInterface
{
protected $serviceManager;
protected $listeners = array();
public function __construct(ServiceLocatorInterface $serviceManager)
{
$this->serviceManager = $serviceManager;
}
public function attach(EventManagerInterface $events)
{
$evm = $events->getSharedManager();
$this->listeners[] = $evm->attach('Application\Service\UserService', 'create.post', array($this, 'notify'));
}
public function detach(EventManagerInterface $events)
{
foreach ($this->listeners as $index => $listener) {
if ($events->detach($listener)) {
unset($this->listeners[$index]);
}
}
}
public function notify(EventInterface $events)
{
$user = $events->getParam('user');
$mailService = $this->serviceManager->get('MailService');
$mailService->sendWelcomeMessage($user);
}
}
Итак, мой вопрос: что является лучшим методом для тестирования приемников событий Zend Framework с помощью PHPUnit, как все методы слушателей прикреплять(), отсоединить (), поставить в известность() и так далее надо правильно тестировать?
Любая помощь приветствуется! Заранее спасибо!
Если вы посмотрите на источник apigility zf-mvc-auth, вы увидите множество примеров тестов слушателя.
https://github.com/zfcampus/zf-mvc-auth/tree/master/test/Authorization
Хотя некоторые могут утверждать, что это не совсем настоящие модульные тесты, и они как бы проходят размытую грань между модульным и функциональным тестами, я считаю, что тестирование слушателей таким способом является самым простым и эффективным способом сделать это без попасть в перегруженный тестовый бардак. Они чисты, просты в написании и понятны.
Вот несколько полезных советов для прикреплять() а также отсоединить (). Сначала протестируем методы Listener в качестве примера:
/**
* {@inheritdoc}
*/
public function attach(EventManagerInterface $events)
{
$this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH,
[$this, 'doAction']);
}
/**
* {@inheritdoc}
*/
public function detach(EventManagerInterface $events)
{
foreach ($this->listeners as $index => $listener) {
if ($events->detach($listener)) {
unset($this->listeners[$index]);
}
}
}
public function doAction($event)
{
// Code truncated.
}
И модульный тест помогает, экземпляр слушателя называется $ This-> слушателем:
/**
* @covers Application\Event\MyListenerClass::attach
*/
public function testAttach()
{
$eventManager = new EventManager();
$this->listener->attach($eventManager);
$events = $eventManager->getEvents();
// Only one event attached to.
$priorityQueue = $eventManager->getListeners($events[0]);
$callBackHandler = $priorityQueue->extract();
$callBackArray = $callBackHandler->getCallback();
$this->assertEquals($this->listener, $callBackArray[0]);
$this->assertEquals('doAction', $callBackArray[1]);
}
/**
* @covers Application\Event\MyListenerClass::detach
*/
public function testDetach()
{
$eventManager = new EventManager();
$this->listener->attach($eventManager);
$this->listener->detach($eventManager);
$events = $eventManager->getEvents();
// Only one event attached to.
$priorityQueue = $eventManager->getListeners($events[0]);
$this->assertEmpty($priorityQueue->toArray());
}
Наконец, также можно использовать EventManager из ServiceManager приложения вместо приведенного здесь примера реализации кода, но этого достаточно, чтобы кто-то начал.