我有自己的事件监听器:
namespace AppBundle\EventHandlers;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
class MyExceptionListener
{
/**
* @var string
*/
private $env;
/**
* @var null|\Twig_Environment
*/
private $twig=null;
private $forOfourExceptions=[
AppBunble\Exceptions\ApiReturnedNoDataException::class,
AppBunble\Exceptions\DatabaseReturnedNoDataException::class,
Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class
];
public function __construct($env,\Twig_Environment $twig)
{
$this->env = $env;
$this->twig=$twig;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
// You get the exception object from the received event
$exception = $event->getException();
$exceptionClass=get_class($exception);
// Customize your response object to display the exception details
$response = new Response();
$content="";
if(in_array($exceptionClass,ExceptionMapping::RETURN_ERROR_FOUR_HUNDRED_FOUR)){
$response ->setStatusCode(Response::HTTP_NOT_FOUND);
$content = $this->twig->render('error_404.html.twig');
} else {
$response ->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
if($this->env == 'dev'){//Only on production set response
return;
}
}
$response->setContent($content);
// Send the modified response object to the event
$event->setResponse($response);
}
}
我做了以下单元测试:
namespace AppBundle\Tests\EventHandlers;
use AppBundle\Exceptions\ApiReturnedNoDataException;
use PHPUnit\Framework\TestCase;
use AppBundle\EventHandlers\MyExceptionListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
class ExceptionListenerTest extends TestCase
{
public function testnoDataExceptionTest()
{
/**
* @var ExceptionListener
*/
$class=$this->constructClass();
$exception=new ApiReturnedNoDataException('giberish');
$responseEvent=$this->getMockBuilder(GetResponseForExceptionEvent::class)
->disableOriginalConstructor()
->getMock();
$responseEvent->method('getException')->willReturn( $exception );
/**
* @var Response
*/
$class->onKernelException($responseEvent);
$this->assertEquals($response->getStatusCode(),Response::HTTP_NOT_FOUND);
}
/**
* @return ExceptionListener
*/
private function constructClass()
{
$twigMock=$this->getMockBuilder(\Twig_Environment::class)
->disableOriginalConstructor()
->getMock();
$twigMock->method('render')->willReturn('');
$exceptionListener= new ExceptionListener('prod',$twigMock);
return $exceptionListener;
}
}
但是phpoUnit正确抛出:
1) AppBundle\Tests\Managers\ExceptionListenerTest::testnoDataExceptionTest
Error: Call to a member function getStatusCode() on null
所以我需要构造一个正确的GetResponseForExceptionEvent
,但是它的构造函数需要传递一个HttpKernelInterface
inn命令来构造它。所以:
MyExceptionListener
进行单元测试?答案 0 :(得分:2)
您测试的方法以GetResponseForExceptionEvent
为参数。这是应该被嘲笑的类。
如果您正在测试HttpKernelInterface
类(已经由Symfony开发人员测试过),那么GetResponseForExceptionEvent
的模拟是可以接受的。
单元测试不测试在另一个类中发生的事情,只测试您的测试类完成其工作并调用其他类所需的方法。这意味着测试MyExceptionListener
实际上断言setResponse
的方法GetResponseForExceptionEvent
被调用正确的参数。