无需数据库调用即可测试Doctrine事件侦听器

时间:2015-07-08 13:23:22

标签: symfony events doctrine-orm

我已经为我的Doctrine实体设置了一些事件监听器,这些监听器工作正常,但我想要对这些事件进行一些自动化测试,以免让您高枕无忧。理想情况下,这些测试不会影响数据库,以便在测试时保持一定的性能水平。

这是我的用户实体的代码(简化),用于确保密码已加密。

// UserBundle/Entity/User.php

/**
 * @ORM\EntityListeners({"UserBundle\EventListener\UserListener"})
 */
class User implements UserInterface, \Serializable
{
    // ...
}

-

// UserBundle/EventListener/UserListener.php

/**
 * @Service
 * @Tag("doctrine.orm.entity_listener")
 */
class UserListener
{
    /**
     * @var Container
     */
    protected $container;

    /**
     * @DI\InjectParams({
     *      "container" = @DI\Inject("service_container")
     * })
     */
    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    /**
     * @ORM\PreUpdate
     */
    public function preUpdateHandler(User $user, PreUpdateEventArgs $args)
    {
        $this->getUserManager()->updatePassword($user);
    }

    /**
     * @return UserManager
     */
    public function getUserManager()
    {
        return $this->container->get('user_manager');
    }
}

我打算在这里测试的是,Doctrine正在更新事件并且我的用户管理器实际调用了方法updatePassword。这是我到目前为止的测试,但我无法解决如何在不执行任何数据库查询的情况下触发事件。

// UserBundle/Tests/EventListener/UserListenerTest.php

class UserListenerTest extends KernelAwareTest
{
    public function testPreUpdate()
    {
        $user = new User();

        $userManager = $this->getMockBuilder('UserBundle\Service\UserManager')
            ->disableOriginalConstructor()
            ->getMock();

        $userManager->expects($this->once())
            ->method('updatePassword')
            ->with($this->equalTo($user));

        $this->container->set('user_manager', $userManager);

       // TODO: how to test?
}

1 个答案:

答案 0 :(得分:0)

如果我以正确的方式理解您的问题,那么您希望实现的是在Doctrine触发更新事件时测试您的侦听器是否被正确调用,而不是测试该事件是否被有效触发。 正如veNuker所说,你必须相信,当事件被解雇时,Doctrine会打电话给你的听众,因为这是它的责任。

但是,如果您想测试听众的行为,可以尝试https://stackoverflow.com/a/22830909/2721918