I know I'm doing something wrong because this is very strange, I'm learning PHPUnit since a few days. The test subject is receive()
controller action:
class ReportController
{
/**
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $dispatcher;
public function __construct(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
/**
* @param \Gremo\SkebbyBundle\Message\InboudSkebbyMessage $message
* @return \Symfony\Component\HttpFoundation\Response
*/
public function receive(InboudSkebbyMessage $message)
{
$this->dispatcher->dispatch(SkebbyEvents::MESSAGE_RECEIVED,
new InboundMessageEvent($message)
);
return new Response();
}
}
As the controller throws an event, I need to mock an event subscriber (implements Symfony\Component\EventDispatcher\EventSubscriberInterface
). There is a static method getSubscribedEvents()
. Test method helper (to get the mock):
public function getMockSubscriber(array $events)
{
$class = $this->getMockClass(
'Symfony\Component\EventDispatcher\EventSubscriberInterface',
array_merge(array_values($events), array('getSubscribedEvents'))
);
// Static stub method
$class::staticExpects($this->once())
->method('getSubscribedEvents')
->will($this->returnValue($events))
;
return new $class;
}
Then in my test method I'm registering the (mock) subscriber, making the request and checking that onMessageReceived()
is invoked exactly one time. The (big, actually) problem is test always succeeds, even if i change the mock to $subscriber->expects($this->never())->method('onMessageReceived')
. Implementation:
public function testApiCall()
{
$client = $this->createClient();
// Router (for route generation) and dispatcher (for subscribing the mock)
$router = $client->getContainer()->get('router');
$dispatcer = $client->getContainer()->get('event_dispatcher');
// Get mock event subscriber
$subscriber = $this->getMockSubscriber(array(
'messsage.received' => 'onMessageReceived'
));
// Register the mock subscriber with the dispatcher
$subscriber->expects($this->once())->method('onMessageReceived');
$dispatcer->addSubscriber($subscriber);
// Make the request
$request = Request::create(
$router->generate('controller_receive'),
'POST',
array(
'sender' => 'sender',
'receiver' => 'receiver',
'text' => 'text',
'timestamp' => time(),
'smsType' => 'smsType'
)
);
$client->getKernel()->handle($request);
}
EDIT: mock subscriber is correctly registered with the dispatcher. var_dump($dispatcher->getListeners())
:
array(7) {
'messsage.received' =>
array(1) {
[0] =>
array(2) {
[0] =>
class Mock_EventSubscriberInterface_19b191af#34 (2) {
...
}
[1] =>
string(17) "onMessageReceived"
}
}