如何测试Symfony中的事件是否已调用EventListener?

时间:2017-06-16 14:48:43

标签: symfony doctrine

我有什么:

我有一个EventListener,用于侦听Symfony中的PreRemove实体事件。

services:
   my_bundle.entity_listener.my_listener:
      class: 'MyCompany\MyBundle\MyListener'
      public: false
      tags:
        - { name: doctrine.orm.entity_listener, entity: 'MyCompany\MyBundle\Entity\MyEntity', event: preRemove }

我想要的是什么:

我希望有一个测试(功能/整合/单元或任何其他真正的),以某种方式检查当移除MyEntity时,正在调用特定的EventListener。

更新

我不想在单元测试中这样做,需要实际检查事件调度程序是否真的会调用该特定事件的特定事件监听器。

更新2

我认为这很明显,但似乎不是 - 解决方案不应该修改EventListener或Event。

更新3

我指定我不关心测试的名称是什么:功能,单位或任何其他。

更新4

解决方案必须保证测试将在任何环境的上下文中传递。所以,如果有人用我的定义扩展我的捆绑和混乱,我仍然应该能够验证EventHandling是否真的有效。

此外,检查处理结果不是一个选项,因为:

  1. EventListener可以做任何事情 - 可能有些情况下我不能简单地检查结果并确定EventListener可以正常工作。

  2. 有人可能会以几乎完全相同的方式处理事件,因此“结果”是相同的,但“方式”是错误的。

5 个答案:

答案 0 :(得分:1)

功能测试用于测试功能;它并不打算测试该功能的实现或该实现的配置。

像你提议的那样的测试将是脆弱的并且不是很有用。

您可能需要测试事件侦听器实现的功能。

答案 1 :(得分:0)

看看这个:Write UnitTest for Symfony EventListener

它可能有所帮助,因为我有(某种)类似的问题/问题

答案 2 :(得分:0)

如何创建编译器传递并将其添加到容器编译的最后阶段:

$container->addCompilerPass(
    new CheckEntityListenerRegistered(),
    PassConfig::TYPE_AFTER_REMOVING,
    -1000
);

最后会执行该编译器。你可以从那一点检查你的听众是否被正确注册,如果是,你可以认为它将由Doctrine的工作单元执行。

答案 3 :(得分:0)

我想我明白你想要什么。您需要集成测试(在所有环境中测试它),而无需修改侦听器,事件调度程序等。

解决方案1 ​​

当你在dev,test或prod symfony上工作加载不同的事件调度程序时,它使用相同的接口和行为,但它是不同的实现(我没有检查doctrine一)。

因此,您将为每个环境配备不同的调度程序,并且您不想知道内部发生了什么。我们称之为黑盒子。

Action delete -> [ black box  ->  listener called ] -> listener effect

你不想看黑盒子或以任何方式触摸它?搜索在系统上具有侦听器的效果。数据库,日志文件,邮件程序等

解决方案2

如果你允许我挂钩黑盒子,我会用一个代理来监听听众,监听是否在代理上调用了监听器。

解决方案3

备选方案,您可以使用symfony探查器中的数据收集器,但您可能不会在生产时启用它。

答案 4 :(得分:0)

也许你可以使用symfony profiler?

请参阅How to Use the Profiler in a Functional Test

在探查器事件部分中,您有两个名为/不称为监听器http://whatever.com/app_dev.php/_profiler/352211?panel=events

的选项卡