【发布时间】:2015-03-19 19:37:53
【问题描述】:
我想第一次使用Prophecy ("phpspec/prophecy-phpunit") 为我的类创建单元测试。我想测试一个在同一个服务中调用另一个函数的函数,代码如下:
class UserManager
{
private $em;
private $passwordHelper;
public function __construct(\Doctrine\ORM\EntityManager $em, \MainBundle\Helper\PasswordHelper $passwordHelper)
{
$this->em = $em;
$this->passwordHelper = $passwordHelper;
}
public function getUserForLdapLogin($ldapUser)
{
$dbUser = $this
->em
->getRepository('MainBundle:User')
->findOneBy(array('username' => $ldapUser->getUsername()));
return (!$dbUser) ?
$this->createUserFromLdap($ldapUser) :
$this->updateUserFromLdap($ldapUser, $dbUser);
}
我遇到的第一个问题是我使用了findOneByUsername,据我所知,Prophecy 不允许您:模拟魔术方法(_call 代表 EntityRepository),模拟不存在的方法,模拟您正在测试的课程。如果这些都是真的,那我就有点麻烦了,这意味着如果不测试类中的其他函数,我就无法测试这个函数。
到目前为止,我的测试如下所示:
class UserManagerTest extends \Prophecy\PhpUnit\ProphecyTestCase
{
public function testGetUserForLdapLoginWithNoUser()
{
$ldapUser = new LdapUser();
$ldapUser->setUsername('username');
$em = $this->prophesize('Doctrine\ORM\EntityManager');
$passwordHelper = $this->prophesize('MainBundle\Helper\PasswordHelper');
$repository = $this->prophesize('Doctrine\ORM\EntityRepository');
$em->getRepository('MainBundle:User')->willReturn($repository);
$repository->findOneBy(array('username' => 'username'))->willReturn(null);
$em->getRepository('MainBundle:User')->shouldBeCalled();
$repository->findOneBy(array('username' => 'username'))->shouldBeCalled();
$service = $this->prophesize('MainBundle\Helper\UserManager')
->willBeConstructedWith(array($em->reveal(), $passwordHelper->reveal()));
$service->reveal();
$service->getUserForLdapLogin($ldapUser);
}
}
当然,测试失败是因为$em 上的承诺和存储库没有实现。如果我实例化我正在测试的类,测试将失败,因为该函数随后在同一个类上调用 createUserFromLdap() 并且未经过测试。
有什么建议吗?
【问题讨论】:
-
我从来没用过,所以我帮不上忙。但是,如果您仍然停留在几天内(即可以应用问题赏金时),请使用 @halfer 联系我,我会添加一个。好问题!
-
到目前为止我发现的最佳答案是,您的班级可能不遵循 S.O.L.I.D 原则并且没有单一职责。所以在你尝试使用预言之前先把你的课程弄清楚。
标签: php symfony phpunit prophecy