我已经为我的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