I've just completed writing a spec for a Doctrine2 repository. The repo contains only one method so far, the spec for which takes in an OAuth Identity token object (that contains an ID that matches up with a database table in my system) and returns either NULL or a UserAccount entity.
Due to the fluent nature of Doctrine query building, my test seems quite verbose, and I have used a lot of lines in my test wiring the 'fluent' aspect of the Query api together.
Repository:
namespace Users\Repository;
use Users\Entity\UserAccount;
use ZF\MvcAuth\Identity;
class UserAccountRepository extends \Doctrine\ORM\EntityRepository
{
public function getFromIdentity(Identity\IdentityInterface $identity)
{
if ($identity instanceof Identity\GuestIdentity) {
return null;
}
if (!$identity instanceof Identity\AuthenticatedIdentity) {
return null;
}
/** @var $identity Identity\AuthenticatedIdentity */
$id = $identity->getRoleId();
if (!is_int($id)) {
return null;
}
return $this->createNamedQuery('u')
->where('u.id = :id')
->setParameter(':id', $id)
->getQuery()
->getResult();
}
}
Spec:
/**
* @mixin \Users\Repository\UserAccountRepository
*/
class UserAccountRepositorySpec extends ObjectBehavior
{
function let(
ORM\EntityManager $em,
ORM\Mapping\ClassMetadata $classMetadata
)
{
$this->beConstructedWith($em, $classMetadata);
}
function it_is_initializable()
{
$this->shouldHaveType('Users\Repository\UserAccountRepository');
}
function it_get_a_user_account_from_an_identity(
ORM\EntityManager $em,
Identity $identity,
TestQuery $query
)
{
$identity->getRoleId()->willReturn(4);
$em->createQuery(Argument::any())->willReturn($query);
$query->where('u.id = :id')->willReturn($query);
$query->setParameter(':id', 4)->willReturn($query);
$query->getQuery(Argument::any())->willReturn($query);
$query->getResult(Argument::any())->shouldBeCalled();
$this->getFromIdentity($identity);
}
function it_should_always_return_null_when_passed_a_guest_identity(
GuestIdentity $identity
)
{
$this->getFromIdentity($identity)->shouldBeNull();
}
}
/** concrete mock due to ORM\Query being final */
class TestQuery extends ORM\AbstractQuery
{
public function getSql(){}
public function _doExecute(){}
public function where(){}
public function getQuery(){}
}