问题描述
我有一个在数据库上运行的命令,然后测试是否有任何公司有重复的名称,然后输出给用户以进行任何补救。
每次测试我想做的是:
- 将数据库更改为指定的一组公司,例如
10 companies with 5 of those having duplicate names
或例如10 companies with 5 having null names
- 运行该测试
通常,如果这是一个函数,我可以在注释中使用数据提供者来提供不同的数据进行测试,例如
* @dataProvider provideFoo
* @param $data
*/
public function testFooBar($data) {...
但是命令没有参数/参数,所以我想我每次都必须更新数据库。
这可以用夹具来完成,还是我应该在每次测试中添加新公司,例如:
public function testFooBar($data) {
$company1 = (new Company())->setName('Company 1');
$this->entityManager->persist($company1);
$this->entityManager->flush();
$commandTester->execute([]);
// rest of test
}
** 编辑 ** 我发现了这个问题,它似乎帮助我建立了测试数据库,我将继续看看现在测试数据库是否启动,我是否可以让装置工作:How to setup a database for test environment in Symfony 4
解决方法
我设法使用这个让它工作:
// tests/Command/FindDuplicatedCompaniesCommandTest.php:
<?php declare(strict_types=1);
namespace App\Tests\Command;
use App\DataFixtures\DuplicatedCompaniesFixtures;
use App\Tests\FixturesTrait;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;
class FindDuplicatedCompaniesCommandTest extends KernelTestCase
{
use FixturesTrait;
public function testExecuteDuplicates()
{
$kernel = static::createKernel();
$application = new Application($kernel);
$command = $application->find('app:find:duplicated-companies');
$commandTester = new CommandTester($command);
$this->addFixture(new DuplicatedCompaniesFixtures());
$this->executeFixtures();
$commandTester->execute([]);
$output = $commandTester->getDisplay();
$this->assertStringContainsString('Detected name',$output);
$this->assertStringContainsString('Company 3',$output);
$this->assertStringContainsString('Company 1',$output);
$this->assertStringNotContainsString('violations',$output);
$this->assertStringNotContainsString('No duplicates',$output);
}
protected function setUp(): void
{
self::bootKernel();
}
}
// src/DataFixtures/DuplicatedCompaniesFixtures.php
<?php declare(strict_types=1);
namespace App\DataFixtures;
use App\Entity\Company;
use DateTimeImmutable;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
/**
* Class DuplicatedCompaniesFixtures
* @package App\DataFixtures
*/
class DuplicatedCompaniesFixtures extends Fixture
{
/**
* @const CO_1_REFERENCE
*/
public const CO_1_REF = 'COONE';
/**
* @const CO_2_REFERENCE
*/
public const CO_2_REF = 'COTWO';
/**
* @const CO_3_REFERENCE
*/
public const CO_3_REF = 'COTHREE';
/**
* @const CO_4_REFERENCE
*/
public const CO_4_REF = 'COFOUR';
/**
* @param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
$company1 = (new Company())
->setName('Company 1')
->setAlphaKey('COMPANYONE')
->setUpdatedAt(new DateTimeImmutable());
$company2 = (new Company())
->setName('Company 1')
->setAlphaKey('COMPANYONE')
->setUpdatedAt(new DateTimeImmutable());
$company3 = (new Company())
->setName('Company 3')
->setAlphaKey('COMPANYTHREE')
->setUpdatedAt(new DateTimeImmutable());
$company4 = (new Company())
->setName('Company 3')
->setAlphaKey('COMPANYFOUR')
->setUpdatedAt(new DateTimeImmutable());
$manager->persist($company1);
$manager->persist($company2);
$manager->persist($company3);
$manager->persist($company4);
$manager->flush();
$this->addReference(self::CO_1_REF,$company1);
$this->addReference(self::CO_2_REF,$company2);
$this->addReference(self::CO_3_REF,$company3);
$this->addReference(self::CO_4_REF,$company4);
}
}
那样,我可以在文件中为每个测试添加不同的夹具,例如如果我想对名称违规进行单独的测试,我会添加 src/DataFixtures/NameViolationCompaniesFixtures.php
并在测试中调用它。