Aşağıdaki örnek, Symfony uygulamalarında PHPUnit ile dinamik olarak gelen yanıtların içeriğini test etmemize yardımcı olur. Dinamik olarak gelen içerikler id ve created_at alanları için geçerlidir. Bu vrilerin her zaman dinamik olmalarının nedeni, Doctrine DataFixtures tarafından yüklenmeleridir.


Mantık


  1. Veriler setUp fonksiyonu ile her bir test için yeniden yüklenirler.

  2. Dinamik olan veriler replaceDynamicData fonksiyonu ile sabit verilerle değiştirilirler.

  3. Doctrine DataFixtures tearDownAfterClass fonksiyonu ile tüm testler bittikten sonra yeniden yüklenirler.

Yapılandırma


Buradaki araylar test, dev ve prod ortamlarının veritabanlarını birbirlerinden ayırmaya yarar. Örneğin api_test, api_dev ve api.


.env.dist


APP_ENV=dev
DATABASE_URL=mysql://root:root@127.0.0.1:3306/api

config/packages/doctrine.yaml


doctrine:
dbal:
...
url: '%env(resolve:DATABASE_URL)%'

config/packages/test/doctrine.yaml


doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%_%kernel.environment%'

config/packages/dev/doctrine.yaml


doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%_%kernel.environment%'

phpunit.xml.dist





xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php">













tests





src




Kurulum


Composer ile phpunit/phpunit ve symfony/browser-kit paketlerini kurmayı unutmayın.


Test dosyaları


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 Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

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

public static function tearDownAfterClass()
{
self::reloadDataFixtures();
}

protected function setUp()
{
self::reloadDataFixtures();

$this->client = static::createClient();
}

protected function replaceDynamicData(string $data): string
{
return preg_replace(
[
'/"id":\d/',
'/\b(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\+(\d{4})\b/',
],
[
'"id":AUTO_ID',
'DATE_ISO8601',
],
$data
);
}

private static function reloadDataFixtures(): void
{
$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());
}

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

CountryControllerTest


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(int $code, string $body)
{
$this->client->request('GET', '/api/v1/countries');

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

public function getAllDataProvider(): iterable
{
return [
[
'$code' => 200,
'$body' => <<[
{
"id": 1,
"code": "gb",
"name": "Great Britain",
"createdAt": "2000-10-29T21:57:00+0100"
},
{
"id": 2,
"code": "tr",
"name": "Turkey",
"createdAt": "2001-11-30T22:58:01+0200"
},
{
"id": 3,
"code": "de",
"name": "Germany",
"createdAt": "2002-12-31T23:59:02+0300"
}
]
EOT
]
];
}
}

Test


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

. 1 / 1 (100%)

Time: 1.77 seconds, Memory: 22.00MB

OK (1 test, 2 assertions)