I am trying to unit test a small class that I consider part of the "business-logic" layer of my project. It mostly just interact's with Doctrine's entity manager and a couple of entities with a many-to-many association. I'm finding that unit testing it while mocking out its dependencies is just ludicrous. Just the code to set up mocks is going to be at least twice as long as the class itself. What am I doing wrong, or should I just not bother doing the mocks and let it interact with a real test database?
Here is the class I am trying to test:
class UserPermissions{
protected $em;
public function __construct($entityManager){
$this->em = $entityManager;
}
/**
* returns user's permissions for all products or specific product
*
**/
public function getFromUUID($uuid, $productId=NULL){
$user = $this->em->find('\MyProject\Entity\User',$uuid);
$product = $productId ? $this->em->find('\MyProject\Entity\Product',$productId) : NULL;
if ($user===null) {
return null;
} else {
$userProducts = $user->getUserProducts();
$result = [];
if ($productId) {
$criteria = Criteria::create()
->where(Criteria::expr()->eq("product",$product))
;
$userProducts = $userProducts->matching($criteria);
}
for ($i = 0; $i < count($userProducts); $i++) {
$productI = $userProducts[$i];
array_push($result, array(
"product" => $productI->getProduct()->getId(),
"permissions" => $productI->getPermissions(),
));
}
return $result;
}
}
}
And here is what my test class is starting to look like:
class UserPermissionsTest extends PHPUnit_Framework_TestCase
{
protected $testService;
protected $mockProduct;
protected $mockUser;
protected $mockUserProduct;
protected function setUp(){
$em = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$emMap = array(
array('\MyProject\Entity\User','a',$this->mockUser),
array('\MyProject\Entity\Product','b',$this->mockProduct),
);
$em->expects($this->any())
->method('find')
->will($this->returnValueMap($emMap));
// $userMockBuilder = $this->getMockBuilder('\MyProject\Entity\User')
// ->disableOriginalConstructor()
$user = $this->getMockBuilder('\MyProject\Entity\User')
->disableOriginalConstructor()
->getMock();
$user->expects($this->any())
->method('getUserProducts')
->will($this->returnValue($this->mockUserProduct);
$this->mockUser=$user;
$userProduct = $this->getMockBuilder('\MyProject\Entity\UserProduct')
->disableOriginalConstructor()
->getMock();
$userProduct->expects($this->any())
->method('matching')
->will($this->returnValue($this->mockProduct);
$this->mockUserProduct = $userProduct;
$product =$this->getMockBuilder('\MyProject\Entity\Product')
->disableOriginalConstructor()
->getMock();
$product->expects($this->any())
->method('getProduct')
->will($this->returnValue($this->mockProduct);
.... and so on. It's obviously not done yet.