在没有数据库调用的情况下测试Doctrine事件监听器



我已经为我的Doctrine实体设置了一些事件监听器,它们工作得很好,但我想对这些实体进行一些自动化测试,以便安心。理想情况下,这些测试不会触及数据库,以便在测试时保持某种水平的性能。

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

// UserBundle/Entity/User.php
/**
 * @ORMEntityListeners({"UserBundleEventListenerUserListener"})
 */
class User implements UserInterface, Serializable
{
    // ...
}

// UserBundle/EventListener/UserListener.php
/**
 * @Service
 * @Tag("doctrine.orm.entity_listener")
 */
class UserListener
{
    /**
     * @var Container
     */
    protected $container;
    /**
     * @DIInjectParams({
     *      "container" = @DIInject("service_container")
     * })
     */
    public function __construct(Container $container)
    {
        $this->container = $container;
    }
    /**
     * @ORMPreUpdate
     */
    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('UserBundleServiceUserManager')
            ->disableOriginalConstructor()
            ->getMock();
        $userManager->expects($this->once())
            ->method('updatePassword')
            ->with($this->equalTo($user));
        $this->container->set('user_manager', $userManager);
       // TODO: how to test?
}

如果我正确理解了您的问题,那么您想要实现的是测试在Doctrine触发更新事件时侦听器是否被正确调用,而不是测试事件是否被有效触发。正如veNuker所说,你必须相信Doctrine会在事件被触发时调用监听器,因为这是它的责任。

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

最新更新