dab-libs / waesel-bundle
用于简化 Symfony 应用集成测试的小型库
Requires
- php: >=8.0
- phpunit/phpunit: ^9.5
- symfony/framework-bundle: ^5.4
- symfony/phpunit-bridge: ^5.4
README
俄语版本Weasel
Weasel - 是一个用于简化 Symfony 应用集成测试的小型库。
安装
通过 Composer 安装
$ composer require --dev dab-libs/waesel-bundle
用法
假设我们想要通过名称或 ID 测试宠物搜索服务。此服务实现了以下接口
interface FindPets { /** @return Pet[] */ public function do(?string $id, ?string $name): array; }
通过 ID、名称或两者都查找宠物。它返回找到的宠物数组,或空数组。
为了测试 FindPets 服务,我们必须首先创建数据库的初始状态。为此,我们创建一个通过实现 Fixture 接口的数据集类
class FindPets_Fixture implements Fixture { const PET_1 = 'pet1'; const PET_2 = 'pet2'; public Pet $pet1; public Pet $pet1_2; public Pet $pet2; public function __construct( private CreatePet $createPet, ) { } public function createData(): void { $this->pet1 = $this->createPet->do(self::PET_1, Pet::CAT); $this->pet1_2 = $this->createPet->do(self::PET_1, Pet::DOG); $this->pet2 = $this->createPet->do(self::PET_2, Pet::CAT); } }
Fixture 接口的 createData 方法专门设计用于创建数据库的初始状态。它将在运行测试之前自动调用。
让我们将 fixture 类作为一个公共服务
services: _defaults: autowire: true autoconfigure: true public: true Weasel\TestBench\Tests\UseCase\Pet\FindPets\FindPets_Fixture:
现在,让我们通过从 Weasel 库中的 DbTestCase 类继承来创建一个测试用例类
class FindPets_Test extends DbTestCase { /** @RequiredForTest) */ private ?FindPets $findPets = null; /** @RequiredForTest) */ private ?FindPets_Fixture $fixture = null; public function testFindTwoByName() { $pets = $this->findPets->do(null, $this->fixture::PET_1); self::assertTrue(in_array($this->fixture->pet1, $pets)); self::assertTrue(in_array($this->fixture->pet1_2, $pets)); self::assertFalse(in_array($this->fixture->pet2, $pets)); } public function testFindOneByName() { $pets = $this->findPets->do(null, $this->fixture::PET_2); self::assertCount(1, $pets); self::assertEquals($this->fixture->pet2, $pets[0]); } public function testFindOneById() { $pets = $this->findPets->do($this->fixture->pet1->getId(), null); self::assertCount(1, $pets); self::assertEquals($this->fixture->pet1, $pets[0]); } }
接下来,我们描述此类中 FindPets 服务和 fixture 的字段。我们用 @RequiredForTest 注解标记它们。现在,FindPets 服务和 fixture 将在运行测试之前自动从 DI 容器请求并分配给相应的字段。这将在基类的 setUp 方法中完成。然后调用 fixture 类的 createData 方法。之后,将执行测试方法,我们可以使用注入的服务。
为什么选择 Weasel
没有 Weasel 的测试中的 Symfony 服务
几乎所有的基于 Symfony 的应用程序的功能都是作为服务实现的。在测试时,这些服务必须从 DI 容器中获取。Symfony 开发者建议这样做 这样
- 初始化 Symfony 内核,
- 使用 KernelTestCase 类的 getContainer 方法获取 DI 容器,
- 从 DI 容器中获取必要的服务。
class NewsletterGeneratorTest extends KernelTestCase { public function testSomething() { self::bootKernel(); $container = static::getContainer(); $newsletterGenerator = $container->get(NewsletterGenerator::class); $newsletter = $newsletterGenerator->generateMonthlyNews(...); $this->assertEquals('...', $newsletter->getContent()); } }
使用 Weasel 的测试中的 Symfony 服务
直接从 DI 容器获取服务不是普通 Symfony 程序员的自然实践。我们通过构造函数参数或通过设置器获取服务。
Weasel 库允许我们通过在测试用例类中描述它们并使用 @RequiredForTest 注解来获取服务
class FindPets_Test extends DbTestCase { /** @RequiredForTest) */ private ?FindPets $findPets = null; /** @RequiredForTest) */ private ?FindPets_Fixture $fixture = null; public function testFindTwoByName() { ... } ... }
这使程序员免去了显式访问 DI 容器的麻烦,使得与服务的工作简单而熟悉。现在程序员可以专注于编写测试,而不会被编写从 DI 容器获取服务的相同类型的代码所分散。
Weasel 类
Weasel 库提供了一些基类用于编写集成和功能测试
- KernelTestCase - 用于不使用数据库的集成测试
- DbTestCase - 用于使用数据库的集成测试
- WebTestCase - 用于不使用数据库的功能测试
- WebDbTestCase - 用于使用数据库的功能测试