为Symfony EventListener编写UnitTest

时间:2014-04-03 07:29:05

标签: symfony phpunit

我这里有一个SymfonyBundle,它实际上不是一个自定义EventDispatcher和一个EventListener。

我如何进行单元测试此代码?

我知道如何为控制器等创建功能测试,但我不确定如何为这个调度员和监听器编写测试..

有人可以指出我正确的方向,谷歌似乎并没有帮助我在这一点。

提前致谢。

Sam J

编辑:04/04/2014 This是我试图为

创建测试的包

我已经设置了测试以检查是否加载了两个服务(调度程序和侦听程序),但现在我需要测试功能性...例如检查在MY调度程序上触发的事件是否在内核上的REAL调度程序上触发.terinate。

编辑 所以我绝对假设我只需要触发我的事件,然后以某种方式进入kernel.terminate,然后检查我的事件是否被真正的调度员,但如何......

1 个答案:

答案 0 :(得分:8)

您可以通过模拟所需的所有必要内容来对您的听众进行单元测试,例如,来自我的项目:

class UploadListenerTest extends \PHPUnit_Framework_TestCase
{
    public function testOnUpload()
    {
        $session = new Session(new MockArraySessionStorage());
        $file = new File(__FILE__);

        $event = new PostPersistEvent($file, new EmptyResponse, new Request(), "", []);

        $listener = new UploadListener($session);
        $listener->onUpload($event);

        $tempFiles = $session->get('_temp_files');

        $this->assertCount(1, $tempFiles);
        $this->assertEquals($tempFiles[0], $file->getFilename());

        $otherFile = new File(__FILE__);

        $event = new PostPersistEvent($otherFile, new EmptyResponse, new Request(), "", []);

        $listener->onUpload($event);

        $tempFiles = $session->get('_temp_files');

        $this->assertCount(2, $tempFiles);
        $this->assertEquals($tempFiles[0], $file->getFilename());
        $this->assertEquals($tempFiles[0], $otherFile->getFilename());
    }
} 

正如您所看到的,我正在创建我的事件监听器所需的每个对象,以便对其行为进行单元测试。

你也可以采用功能性的方式。引导Symfony内核并为事件触发创建条件,然后测试触发事件后需要的预期条件:

public function testUploadNoFilesNoAjaxLoggedUser()
{
    $this->loginUser($this->getDummyUser());

    $response = $this->requestRoute(self::UPLOAD_ROUTE, "POST");

    $this->assertResponseRedirect("panel_index", $response);
}

如您所见,我首先记录用户,然后对上传表单进行实际请求。之后我断言我的响应应该是重定向到主面板。 Symfony正在触发事件,这个事件正在返回我需要断言的RedirectResponse。

我的建议是你尝试编写单元测试和功能测试,它会使你的应用程序保持更稳定的状态。

修改

在此PR中添加了有关如何测试事件调度程序本身的具体问题的答案:

https://github.com/whitewhidow/AsyncDispatcherBundle/pull/1/files