我是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函数。
答案 0 :(得分:2)
你不能像你尝试过那样使用“链接”。原因是方法getMock
和will
返回不同的对象。这就是你失去真正的模拟对象的原因。试试这个:
$exceptionMock = $this->getMock('\Exception');
$exceptionMock->expects($this->once())
->method('getCode')
->will($this->returnValue('404'));
修改强>
确定。问题是你无法模拟getCode
方法,因为它是final
而且用PHPUnit模拟final
和private
方法是不可能的。
我的建议是:只需准备一个你想要的异常对象,并将其作为返回值传递给事件模拟:
$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');
查看文档了解更多...我希望你会喜欢它。