3

これは非常に奇妙であるため、私は何か間違ったことをしていることを知っています。私は数日からPHPUnitを学んでいます。テスト対象はreceive()コントローラー アクションです。

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();
    }
}

コントローラーがイベントをスローするので、イベント サブスクライバー (implements Symfony\Component\EventDispatcher\EventSubscriberInterface) をモックする必要があります。静的メソッドがありますgetSubscribedEvents()。テスト メソッド ヘルパー (モックを取得するため):

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;
}

次に、テスト メソッドで (モック) サブスクライバーを登録し、要求を作成して、onMessageReceived()1 回だけ呼び出されることを確認します。(実際には大きな)問題は、モックを に変更しても、常にテストが成功する$subscriber->expects($this->never())->method('onMessageReceived')ことです。実装:

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 : モック サブスクライバーはディスパッチャーに正しく登録されています。var_dump($dispatcher->getListeners()):

array(7) {
  'messsage.received' =>
  array(1) {
    [0] =>
    array(2) {
      [0] =>
      class Mock_EventSubscriberInterface_19b191af#34 (2) {
        ...
      }
      [1] =>
      string(17) "onMessageReceived"
    }
  }
4

1 に答える 1

3

クラス名から新しいオブジェクトを作成する代わりに、モックされたオブジェクトを使用します。

public function getMockSubscriber(array $events)
{
    $subscriberMock = $this->getMock(
        'Symfony\Component\EventDispatcher\EventSubscriberInterface',
        array_merge(array_values($events), array('getSubscribedEvents'))
    );

    // Static stub method
    $class = get_class(subscriberMock);
    $class::staticExpects($this->once())
        ->method('getSubscribedEvents')
        ->will($this->returnValue($events))
    ;

    return $subscriberMock;
}
于 2012-09-27T20:51:14.973 に答える