Bu örneğimizde PHPUnit ile symfony console command class'ı test edeceğiz.


Composer.json


Ayarlarımız aşağıdaki gibidir.


{
...
"require": {
"php": ">=7.1.1",
...
},
"require-dev": {
"phpunit/phpunit": "^6.4"
},
"config": {
"platform": {
"php": "7.1.11"
},
...
},
...
}

CustomerCommand


Test için $ bin/console customer --id=1 komutunu çalıştırabilirsiniz.


namespace PhpunitBundle\Command;

use PhpunitBundle\Entity\Customer;
use PhpunitBundle\Repository\CustomerRepository;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class CustomerCommand extends Command
{
private $customerRepository;

public function __construct(
CustomerRepository $customerRepository
) {
parent::__construct();

$this->customerRepository = $customerRepository;
}

protected function configure()
{
$this
->setName('customer')
->addOption('id', null, InputOption::VALUE_REQUIRED);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$customer = $this->customerRepository->findOneById($input->getOption('id'));
if (!$customer instanceof Customer) {
throw new BadRequestHttpException(
sprintf('Customer with id [%s] not found', $input->getOption('id'))
);
}

$output->writeln($customer->getName());
}
}

services:
phpunit.command.customer:
class: PhpunitBundle\Command\CustomerCommand
tags:
- { name: console.command }
arguments:
- "@phpunit.repository.customer"

CustomerCommandTest


namespace tests\PhpunitBundle\Command;

use DateTime;
use PhpunitBundle\Command\CustomerCommand;
use PhpunitBundle\Entity\Customer;
use PhpunitBundle\Repository\CustomerRepository;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class CustomerCommandTest extends TestCase
{
/** @var CustomerRepository|PHPUnit_Framework_MockObject_MockObject */
private $customerRepositoryMock;
/** @var CommandTester */
private $commandTester;

protected function setUp()
{
$this->customerRepositoryMock = $this->getMockBuilder(CustomerRepository::class)
->disableOriginalConstructor()
->getMock();

$application = new Application();
$application->add(new CustomerCommand($this->customerRepositoryMock));
$command = $application->find('customer');
$this->commandTester = new CommandTester($command);
}

protected function tearDown()
{
$this->customerRepositoryMock = null;
$this->commandTester = null;
}

public function testExecute()
{
$id = 1;
$customer = new Customer();
$customer->setId($id);
$customer->setName('Name 1');
$customer->setDob(new DateTime());

$this->customerRepositoryMock
->expects($this->once())
->method('findOneById')
->with($id)
->willReturn($customer);

$this->commandTester->execute(['--id' => $id]);

$this->assertEquals('Name 1', trim($this->commandTester->getDisplay()));
}

public function testExecuteShouldThrowExceptionForInvalidCustomerId()
{
$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->commandTester->execute(['--id' => $id]);
}
}