【问题标题】:PHPUnit test always succeeds, both with $this->once() and $this->never()?PHPUnit 测试总是成功,无论是 $this->once() 还是 $this->never()?
【发布时间】:2012-09-19 09:09:33
【问题描述】:

我知道我做错了什么,因为这很奇怪,我从几天开始就在学习 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();
    }
}

当控制器抛出一个事件时,我需要模拟一个事件订阅者(实现 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() 是否被调用了一次。 (实际上很大)问题是测试总是成功,即使我将模拟更改为$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);
}

编辑:模拟订阅者已正确注册到调度程序。 var_dump($dispatcher->getListeners()):

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

【问题讨论】:

    标签: php unit-testing testing symfony phpunit


    【解决方案1】:

    我会使用模拟对象,而不是根据类名创建一个新对象:

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

    【讨论】:

    • 有效!作品!作品!谢谢......显然我需要弄清楚我错过了什么。
    猜你喜欢
    • 1970-01-01
    • 2012-01-14
    • 2016-02-07
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    相关资源
    最近更新 更多