PHPunit mock - 在返回的模拟中调用函数

时间:2013-11-17 08:49:15

标签: unit-testing symfony mocking phpunit

我是phpunit和mocking的新手,我想在我的symfony2项目中测试一个Listener,什么是内核异常监听器。

这是我要测试的课程:

public function onKernelException(GetResponseForExceptionEvent $event)
{
    $code = $event->getException()->getCode();
    if($code == 403)
    {
        $request = $event->getRequest();
        $session = $request->getSession();
        $session->getFlashBag()->add('notice', 'message');
        $session->set('hardRedirect', $request->getUri());
    }
}

首先我只是想测试,所以如果代码是404则没有任何反应,这是我写的测试:

public function testWrongStatusCode()
{
    $exceptionMock = $this->getMock('Exception')
                      ->expects($this->once())
                      ->method('getCode')
                      ->will($this->returnValue('404'));

    $eventMock = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent')
                      ->disableOriginalConstructor()
                      ->getMock();
    $eventMock->expects($this->once())
              ->method('getException')
              ->will($this->returnValue($exceptionMock));

//here call the listener
}

但PHPunit说,从未调用过getCode函数。

3 个答案:

答案 0 :(得分:2)

你不能像你尝试过那样使用“链接”。原因是方法getMockwill返回不同的对象。这就是你失去真正的模拟对象的原因。试试这个:

$exceptionMock = $this->getMock('\Exception');
$exceptionMock->expects($this->once())
    ->method('getCode')
    ->will($this->returnValue('404'));

修改

确定。问题是你无法模拟getCode方法,因为它是final而且用PHPUnit模拟finalprivate方法是不可能的。

我的建议是:只需准备一个你想要的异常对象,并将其作为返回值传递给事件模拟:

$exception = new \Exception("", 404);
(...)
$eventMock->expects($this->once())
    ->method('getException')
    ->will($this->returnValue($exception));

答案 1 :(得分:0)

这就是我模拟 getCode() 函数的方式。它实际上是从 ResponseInterface::getStatusCode() 函数中调用的,因此您需要模拟:

$guzzle->shouldReceive('get')
    ->once()
    ->with(
        $url
    )
    ->andThrows(new ClientException(
        "",
        Mockery::mock(RequestInterface::class),
        Mockery::mock(ResponseInterface::class, [
            'getStatusCode' => 404,
        ]),
    ));

答案 2 :(得分:-1)

您可以将mockery library与PHPUnit结合使用,这是一个很棒的工具,可以让您的生活更轻松。

$exceptionMock = \Mockery::mock('GetResponseForExceptionEvent');
$exceptionMock->shouldReceive('getException->getCode')->andReturn('404');

查看文档了解更多...我希望你会喜欢它。