如何在 Symfony 中实现自己的 Faker 提供者

How to implement your own Faker provider in Symfony

为了减少我的 fixture classes 中的一些代码重复,我想在我的 Symfony 5 应用程序中为 Faker (fakerphp/faker) 创建一个自定义提供程序。我在哪里可以在我的应用程序中创建一个自定义的伪造者提供者?请注意,我是 Symfony 开发的新手。

我找到了与此主题相关的内容 ,但是 Symfony 当然有不同的项目设置。

读到 the documentation of a related library,我希望我可以使用 $faker->addProvider(),但我又不知道这段代码应该放在我的 Symfony 应用程序中的什么地方。

我想我应该为这个功能做一个服务,或者我应该把它添加到我的 BaseFixture class?但这些对我来说只是胡乱猜测。

将提供商放在哪里是一个主观问题。有些使用 src/Test/(或命名空间 App\Test)来测试相关代码,但不是实际测试。其他人会将它放在 tests/ 目录中某处的测试旁边,例如tests/Faker/(使用命名空间 App\Tests\Faker)。后者的好处是,classes 只会被 autoload-dev 获取,而不会在生产中获取。

关于问题的第二部分,如何将提供程序添加到 Faker 取决于您在测试中如何使用它,或者更准确地说,如果您想从容器中获取共享的 faker 实例或手动创建一个.特别是如果你的提供依赖于其他服务,比如 Doctrine,你可能想在容器中注册它,或者你应该重新考虑你的提供者,因为依赖数据库可能会导致问题,例如当您重置测试数据库时,您的提供商的数据池可能会消失。

我会在你的测试中创建一个 faker 实例,因为启动 Faker 的成本相对较低,如果多次进行,它不应该明显减慢你的测试,你将被迫避免将提供者绑定到意外地从您的生产代码中获取服务。如果这与您相关,您还可以更好地控制如何创建 faker 实例以及要为特定测试加载哪些提供程序。例如,您可以在测试的 setUp 方法中创建一个实例:

class MyTest extends TestCase
{
    private $faker;

    protected function setUp(): void
    {
        // The Faker\Factory will create a ready to use Faker Generator
        $this->faker = Factory::create();
        $this->faker->addProvider(new MyCustomProvider());
    }

    public function testSomething(): void
    {
        $title = $this->faker->title;
    }
}

Factory 将创建一个新的 Faker\Generator,其中包含所有已注册的默认提供程序。如果您只想在其中拥有自己的提供商,可以查看 at the code 。您可以共享它,而不是在每个测试中复制此代码,例如通过创建您自己的 TestCase-class 来扩展您的测试而不是 PHPUnit 提供的测试,或者您可以使用特征。我认为这两种方法都可以,但如果您还不熟悉 Traits,则可能有自己的基础 TestCase。

使用上面的 setUp 方法,您还可以查看 how Symfony's Service Container works, especially how to create services through a factory 然后,例如创建一个 config/services_test.yaml ,您可以在其中创建一个 faker 实例,您可以在扩展启动 Symfony 内核后的 WebTestCase 或 KernelTestCase。