我想第一次使用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
和預言,據我所知去,不允許你到:模擬魔法方法(_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
的承諾,和倉庫都沒有履行。如果我實例化了正在測試的類,則測試失敗,因爲該函數然後在同一個類上調用並且未經測試。
有什麼建議嗎?
我從來沒有用過它,所以不能自己幫忙。但是,如果你仍然在幾天之內陷入困境(即可以應用問題賞金),請使用@halfer ping我,然後添加一個。好問題! – halfer 2015-01-21 14:50:51
最佳答案我發現到目前爲止,您的班級可能不遵循S.O.L.I.D原則,並且沒有單獨的責任。因此,在嘗試使用預言之前,請讓你的課程順利進行。 – anegrea 2015-01-22 15:55:31