Bu örnekte veritabanındaki verileri sürekli yeniden yüklememek için, Doctrine DataFixture değişikliklerini her bir PHPUnit testlerinde geri alacağız. Bu sayede veriler sadece bir kereye mahsus olmak suretiyle test başında yüklenecekler ve değişiklikler her testin sonunda geri alınarak performans artacak. Bu işlemin sonucunda aynı veriyi kullanan testlerimiz kırılmayacaklar.


AbstractTest


declare(strict_types=1);

namespace App\Tests;

use App\DataFixtures\CountryFixtures;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class AbstractTest extends WebTestCase
{
/** @var Client $client */
protected $client;
/** @var EntityManagerInterface */
private $entityManager;

public static function setUpBeforeClass()
{
$kernel = static::createKernel();
$kernel->boot();
$entityManager = $kernel->getContainer()->get('doctrine')->getManager();

$loader = new Loader();
foreach (self::getFixtures() as $fixture) {
$loader->addFixture($fixture);
}

$purger = new ORMPurger();
$purger->setPurgeMode(ORMPurger::PURGE_MODE_DELETE);
$executor = new ORMExecutor($entityManager, $purger);
$executor->execute($loader->getFixtures());
}

protected function setUp()
{
$this->client = static::createClient();
$this->client->disableReboot();

$this->entityManager = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$this->entityManager->beginTransaction();
$this->entityManager->getConnection()->setAutoCommit(false);
}

protected function tearDown()
{
if ($this->entityManager->getConnection()->isTransactionActive()) {
$this->entityManager->rollback();
}
}

private static function getFixtures(): iterable
{
return [
new CountryFixtures(),
];
}
}

CountryControllerTest


Aşağıdaki update_one fonksiyonu, veritabanında Great Britain kaydının code ve name değerlerini değiştirir. Bu fonksiyonu sadece gösteri amacıyla testi mümkün olduğunca kısa tutmak için GET yöntemi ile yaptım. code "abc" olarak, name ise arka planda "Hello" olarak değiştirildi. Aşağıdaki test sonucunda göreceğiniz gibi, get_all_returns_valid_response_2 kırılmadı!


declare(strict_types=1);

namespace App\Tests\Controller;

use App\Tests\AbstractTest;

class CountryControllerTest extends AbstractTest
{
/**
* @test
* @dataProvider getAllDataProvider
*/
public function get_all_returns_valid_response_1(int $code, string $body): void
{
$this->client->request('GET', '/api/v1/countries');

$this->assertSame($code, $this->client->getResponse()->getStatusCode());
$this->assertSame($code, $this->client->getResponse()->getStatusCode());
$this->assertSame($body, $this->client->getResponse()->getContent());
}

/**
* @test
*/
public function update_one(): void
{
$this->client->request('GET', '/api/v1/countries/1');

$this->assertSame(200, $this->client->getResponse()->getStatusCode());
}

/**
* @test
* @dataProvider getAllDataProvider
*/
public function get_all_returns_valid_response_2(int $code, string $body): void
{
$this->client->request('GET', '/api/v1/countries');

$this->assertSame($code, $this->client->getResponse()->getStatusCode());
$this->assertSame($body, $this->client->getResponse()->getContent());
}

public function getAllDataProvider(): iterable
{
return [
[
'$code' => 200,
'$body' => <<[
{
"id": 1,
"code": "gb",
"name": "Great Britain",
},
{
"id": 2,
"code": "tr",
"name": "Turkey",
},
{
"id": 3,
"code": "de",
"name": "Germany",
}
]
EOT
]
];
}
}

Test


$ vendor/bin/phpunit --filter CountryControllerTest tests/Controller/CountryControllerTest.php 
PHPUnit 7.1.5 by Sebastian Bergmann and contributors.

... 3 / 3 (100%)

Time: 592 ms, Memory: 12.00MB

OK (3 tests, 5 assertions)