dab-libs/waesel-bundle

用于简化 Symfony 应用集成测试的小型库

安装: 1

依赖: 0

建议者: 0

安全性: 0

星标: 0

关注者: 1

分支: 0

开放问题: 0

类型:symfony-bundle

1.0.8 2022-05-12 08:56 UTC

This package is not auto-updated.

Last update: 2024-09-26 20:21:15 UTC


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 开发者建议这样做 这样

  1. 初始化 Symfony 内核,
  2. 使用 KernelTestCase 类的 getContainer 方法获取 DI 容器,
  3. 从 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 - 用于使用数据库的功能测试