28/10/2017 - PHPUNIT, SYMFONY
Bu örneğimizde PHPUnit ile create (yaratma), read (okuma), update (yenileme) ve delete (silme) operasyonlarını yapan bir servis class'ı test edeceğiz.
Ayarlarımız aşağıdaki gibidir.
{
...
"require": {
"php": ">=7.1.1",
...
},
"require-dev": {
"phpunit/phpunit": "^6.4"
},
"config": {
"platform": {
"php": "7.1.11"
},
...
},
...
}
namespace PhpunitBundle\Service;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use PhpunitBundle\Entity\Customer;
use PhpunitBundle\Repository\CustomerRepository;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class CustomerService
{
private $customerRepository;
private $entityManager;
public function __construct(
CustomerRepository $customerRepository,
EntityManagerInterface $entityManager
) {
$this->customerRepository = $customerRepository;
$this->entityManager = $entityManager;
}
public function getAll()
{
return $this->customerRepository->findAll();
}
public function getOne($id)
{
return $this->customerRepository->findOneById($id);
}
public function createOne(array $payload)
{
$customer = new Customer();
$customer->setName($payload['name']);
$customer->setDob(new DateTime($payload['dob']));
$this->entityManager->persist($customer);
$this->entityManager->flush();
return $customer->getId();
}
public function updateOne(array $payload, $id)
{
$customer = $this->customerRepository->findOneById($id);
if (!$customer instanceof Customer) {
throw new BadRequestHttpException(sprintf('Customer with id [%s] not found', $id));
}
$customer->setName($payload['name']);
$customer->setDob(new DateTime($payload['dob']));
$this->entityManager->flush();
}
public function deleteOne($id)
{
$customer = $this->customerRepository->findOneById($id);
if (!$customer instanceof Customer) {
throw new BadRequestHttpException(sprintf('Customer with id [%s] not found', $id));
}
$this->entityManager->remove($customer);
$this->entityManager->flush();
}
}
services:
phpunit.service.customer:
class: PhpunitBundle\Service\CustomerService
arguments:
- "@phpunit.repository.customer"
- "@doctrine.orm.entity_manager"
namespace PhpunitBundle\Repository;
use Doctrine\ORM\EntityRepository;
class CustomerRepository extends EntityRepository
{
public function findAll()
{
return $this->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}
public function findOneById($id)
{
return $this->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}
services:
phpunit.repository.customer:
class: PhpunitBundle\Service\CustomerRepository
factory: [ "@doctrine.orm.entity_manager", getRepository ]
arguments:
- PhpunitBundle\Entity\Customer
namespace tests\PhpunitBundle\Service;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use PhpunitBundle\Entity\Customer;
use PhpunitBundle\Repository\CustomerRepository;
use PhpunitBundle\Service\CustomerService;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class CustomerServiceTest extends TestCase
{
/** @var CustomerRepository|PHPUnit_Framework_MockObject_MockObject */
private $customerRepositoryMock;
/** @var EntityManagerInterface|PHPUnit_Framework_MockObject_MockObject */
private $entityManagerInterfaceMock;
/** @var CustomerService */
private $customerService;
protected function setUp()
{
$this->customerRepositoryMock = $this->getMockBuilder(CustomerRepository::class)
->disableOriginalConstructor()
->getMock();
$this->entityManagerInterfaceMock = $this->getMockBuilder(EntityManagerInterface::class)
->disableOriginalConstructor()
->getMock();
$this->customerService = new CustomerService(
$this->customerRepositoryMock,
$this->entityManagerInterfaceMock
);
}
protected function tearDown()
{
$this->customerRepositoryMock = null;
$this->entityManagerInterfaceMock = null;
$this->customerService = null;
}
/**
* @dataProvider getAllCustomerDataProvider
*/
public function testGetAll($customers, $expected)
{
$this->customerRepositoryMock
->expects($this->once())
->method('findAll')
->willReturn($customers);
$result = $this->customerService->getAll();
$this->assertEquals($expected, $result);
}
/**
* @dataProvider getOneCustomerDataProvider
*/
public function testGetOne($id, $customer, $expected)
{
$this->customerRepositoryMock
->expects($this->any())
->method('findOneById')
->with($id)
->willReturn($customer);
$result = $this->customerService->getOne($id);
$this->assertEquals($expected, $result);
}
public function testCreateOne()
{
$customer = new Customer();
$customer->setName('Name 1');
$customer->setDob(new DateTime('2017-01-01'));
$this->entityManagerInterfaceMock
->expects($this->once())
->method('persist')
->with($customer);
$this->entityManagerInterfaceMock
->expects($this->once())
->method('flush');
$result = $this->customerService->createOne(['name' => 'Name 1', 'dob' => '2017-01-01']);
$this->assertEquals($customer->getId(), $result);
$this->assertEquals($customer->getName(), 'Name 1');
$this->assertEquals($customer->getDob(), new DateTime('2017-01-01'));
}
public function testUpdateOneShouldThrowExceptionForInvalidCustomerId()
{
$id = 666;
$this->customerRepositoryMock
->expects($this->once())
->method('findOneById')
->with($id)
->willReturn(null);
$this->expectException(BadRequestHttpException::class);
$this->expectExceptionMessage(sprintf('Customer with id [%s] not found', $id));
$this->customerService->updateOne(['name' => 'New Name 1', 'dob' => '2017-01-11'], $id);
}
/**
* @dataProvider getUpdateOneCustomerDataProvider
*/
public function testUpdateOne($id, $customer)
{
$this->customerRepositoryMock
->expects($this->once())
->method('findOneById')
->with($id)
->willReturn($customer);
$this->entityManagerInterfaceMock
->expects($this->once())
->method('flush');
$this->customerService->updateOne(['name' => 'New Name 1', 'dob' => '2017-01-11'], $id);
$this->assertEquals($customer->getName(), 'New Name 1');
$this->assertEquals($customer->getDob(), new DateTime('2017-01-11'));
}
public function testDeleteOneShouldThrowExceptionForInvalidCustomerId()
{
$id = 666;
$this->customerRepositoryMock
->expects($this->once())
->method('findOneById')
->with($id)
->willReturn(null);
$this->expectException(BadRequestHttpException::class);
$this->expectExceptionMessage(sprintf('Customer with id [%s] not found', $id));
$this->customerService->deleteOne($id);
}
/**
* @dataProvider getRemoveOneCustomerDataProvider
*/
public function testDeleteOne($id, $customer)
{
$this->customerRepositoryMock
->expects($this->once())
->method('findOneById')
->with($id)
->willReturn($customer);
$this->entityManagerInterfaceMock
->expects($this->once())
->method('remove')
->with($customer);
$this->entityManagerInterfaceMock
->expects($this->once())
->method('flush');
$this->customerService->deleteOne($id);
}
public function getAllCustomerDataProvider()
{
$c0 = [];
$customers0 = [$c0];
$c1 = new Customer();
$c1->setId(1);
$c1->setName('Name 1');
$c1->setDob(new DateTime());
$customers1 = [$c1];
$c2 = new Customer();
$c2->setId(2);
$c2->setName('Name 2');
$c2->setDob(new DateTime());
$customers2 = [$c1, $c2];
return [
[$customers0, $customers0],
[$customers1, $customers1],
[$customers2, $customers2]
];
}
public function getOneCustomerDataProvider()
{
$id0 = 0;
$c0 = null;
$customers0 = $c0;
$id1 = 1;
$c1 = new Customer();
$c1->setId($id1);
$c1->setName('Name 1');
$c1->setDob(new DateTime());
$customers1 = $c1;
return [
[$id0, $customers0, $c0],
[$id1, $customers1, $c1],
];
}
public function getUpdateOneCustomerDataProvider()
{
$customer = new Customer();
$customer->setId(1);
$customer->setName('Name 1');
$customer->setDob(new DateTime('2017-01-01'));
return [
[1, $customer],
];
}
public function getRemoveOneCustomerDataProvider()
{
$customer = new Customer();
$customer->setId(1);
$customer->setName('Name 1');
$customer->setDob(new DateTime('2017-01-01'));
return [
[1, $customer],
];
}
}