vladshut/factory 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

vladshut/factory

最新稳定版本:v1.0.0

Composer 安装命令:

composer require vladshut/factory

包简介

Library for generating objects, arrays in testing environment

README 文档

README

pipeline status coverage report

Base classes for creating factories for data (arrays, objects).

Inspired by laravel factory library.

Installation

composer require --dev vladshut/factory

Usage examples

<?php
declare(strict_types=1);

namespace Tests\Helpers;

// We have next classes objects of which we want to create using factories 

final class User
{
    private string $name;
    private array $tags = [];

    public function __construct(
        public readonly string $username,
        public readonly string $email,
        public readonly ?string $country,
        public readonly ?UserProfile $profile = null,
        private UserRole $role = UserRole::USER,
    ) {
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function setRole(UserRole $role): void
    {
        $this->role = $role;
    }

    public function role(): UserRole
    {
        return $this->role;
    }

    public function username(): string
    {
        return $this->username;
    }

    public function addTag(string $tag): void
    {
        $this->tags[] = $tag;
    }

    public function name(): string
    {
        return $this->name;
    }
}

final readonly class UserProfile
{
    public function __construct(
        public readonly string $bio,
    ) {
    }
}

// Let's create factories for these classes

/**
 * @extends Factory<User>
 */
final class UserFactory extends Factory
{
    public function defaultState(): array
    {
        return [
            'username' => $this->faker->userName(),
            'email' => $this->faker->email,
            'name' => $this->faker->name(),
            'profile' => UserProfileFactory::new(),
            'role' => $this->randomEnum(UserRole::class),
            'tags' => $this->collect(3, fn () => $this->faker->word),
            'country' => $this->optional($this->faker->countryCode()),
        ];
    }

    public function admin(): self
    {
        return $this->state(fn () => ['role' => UserRole::ADMIN]);
    }

    public function withEmail(string $email): self
    {
        return $this->state(['email' => $email]);
    }

    public function makeItem(array $state): User
    {
        $user = new User(
            $state['username'],
            $state['email'],
            $state['country'],
            $state['profile'],
        );

        $user->setName($state['name']);
        $user->setRole($state['role']);

        foreach ($state['tags'] as $tag) {
            $user->addTag($tag);
        }

        return $user;
    }

    protected function fixFinalState(array $state): array
    {
        if ($state['role'] === UserRole::ADMIN) {
            $state['name'] .= ' (admin)';
        }

        return $state;
    }
}

final class UserArrayFactory extends RawFactory
{
    public function defaultState(): array
    {
        return [
            'username' => $this->faker->userName(),
            'email' => $this->faker->email,
            'name' => $this->faker->name(),
            'country' => $this->optional($this->faker->countryCode()),
            'role' => $this->randomEnum(UserRole::class),
            'tags' => $this->collect(3, fn () => $this->faker->word()),
        ];
    }
}

/**
 * @extends Factory<UserProfile>
 */
final class UserProfileFactory extends Factory
{
    public function makeItem(array $state): UserProfile
    {
        return new UserProfile(...$state);
    }

    public function defaultState(): array
    {
        return [
            'bio' => $this->faker->text(),
        ];
    }
}

// Now these factories can be used to create objects
$user = UserFactory::new()->make();
$userArray = UserFactory::new()->raw()->make();
$userArray = UserArrayFactory::new()->make();

// It is possible to create array of objects
$users = UserFactory::new()->count(10)->make();
$usersArray = UserFactory::new()->count(10)->raw()->make();

// Using states allow to create objects with overridden properties
$admin = UserFactory::new()->state(['role' => 'admin'])->make();

// It is possible to use custom state to override properties
$admin = UserFactory::new()->admin()->make();

// It is possible to create single object using makeOne method
$admin = UserFactory::new()->admin()->makeOne();

// Also it is possible to pass state to the make, makeOne methods
$user = UserFactory::new()->make(['role' => 'admin']);
$user = UserFactory::new()->makeOne(['role' => 'admin']);

// It is possible to create multiple objects with a sequence of states
$states = [['email' => 'foo@mail.com'], ['email' => 'bar@mail.com']];
$users = UserFactory::new()->makeMany($states); // will create 2 users: one with foo@mail, another with bar@mail

Tests

make test:run

buy me a coffe

统计信息

  • 总下载量: 3
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-08-06