Heim > PHP-Framework > Laravel > Wie verwende ich die Modellfabrik in der Laravel-Anwendung?

Wie verwende ich die Modellfabrik in der Laravel-Anwendung?

青灯夜游
Freigeben: 2022-11-28 20:26:22
nach vorne
1174 Leute haben es durchsucht

Wie verwende ich die Modellfabrik in der Laravel-Anwendung? Der folgende Artikel stellt Ihnen die Verwendung der Laravel-Modelltechnik beim Testen vor. Ich hoffe, er wird Ihnen hilfreich sein!

Wie verwende ich die Modellfabrik in der Laravel-Anwendung?

Laravel Model Factory ist eine der besten Funktionen, die Sie beim Testen Ihrer Anwendung verwenden können. Sie bieten eine Möglichkeit, vorhersehbare und leicht reproduzierbare Daten zu definieren, sodass Ihre Tests konsistent und kontrollierbar bleiben.

Beginnen wir mit einem einfachen Beispiel. Wir haben eine Anwendung zum Bloggen, daher haben wir natürlich ein Post-Modell mit dem Status „Veröffentlicht“, „Entwurf“ oder „In der Warteschlange“. Schauen wir uns für dieses Beispiel das Eloquent-Modell an:

declare(strict_types=1);

namespace App\Models;

use App\Publishing\Enums\PostStatus;
use Illuminate\Database\Model;

class Post extends Model
{
    protected $fillable = [
        'title',
        'slug',
        'content',
        'status',
        'published_at',
    ];

    protected $casts = [
        'status' => PostStatus::class,
        'published_at' => 'datetime',
    ];
}
Nach dem Login kopieren

Wie Sie hier sehen können, haben wir ein Enum für die Statusspalte, das wir nun entwerfen werden. Durch die Verwendung von Aufzählungen können wir hier die Funktionen von PHP 8.1 anstelle einfacher Zeichenfolgen, boolescher Flags oder verwirrender Datenbankaufzählungen nutzen.

 declare(strict_types=1);

namespace App\Publishing\Enums;

enum PostStatus: string
{
    case PUBLISHED = 'published';
    case DRAFT = 'draft';
    case QUEUED = 'queued';
}
Nach dem Login kopieren

Jetzt kommen wir zurück zu dem Thema, das wir hier diskutieren: Model Factory. Eine einfache Fabrik sieht einfach aus:

 declare(strict_types=1);

namespace Database\Factories;

use App\Models\Post;
use App\Publishing\Enums\PostStatus;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition(): array
    {
        $title = $this->faker->sentence();
        $status = Arr::random(PostStatus::cases());

        return [
            'title' => $title,
            'slug' => Str::slug($title),
            'content' => $this->faker->paragraph(),
            'status' => $status->value,
            'published_at' => $status === PostStatus::PUBLISHED
                ? now()
                : null,
        ];
    }
}
Nach dem Login kopieren

In unseren Tests können wir jetzt also schnell unsere Post-Fabrik anrufen, um einen Beitrag für uns zu erstellen. Mal sehen, wie wir das machen können:

 it('can update a post', function () {
    $post = Post::factory()->create();

    putJson(
        route('api.posts.update', $post->slug),
        ['content' => 'test content',
    )->assertSuccessful();

    expect(
        $post->refresh()
    )->content->toEqual('test content');
});
Nach dem Login kopieren
Nach dem Login kopieren

Ein ziemlich einfacher Test, aber was passiert, wenn unsere Geschäftsregeln besagen, dass Sie nur bestimmte Spalten basierend auf dem Beitragstyp aktualisieren können? Lassen Sie uns unseren Test umgestalten, um sicherzustellen, dass wir dies tun können:

it('can update a post', function () {
    $post = Post::factory()->create([
        'type' => PostStatus::DRAFT->value,
    ]);

    putJson(
        route('api.posts.update', $post->slug),
        ['content' => 'test content',
    )->assertSuccessful();

    expect(
        $post->refresh()
    )->content->toEqual('test content');
});
Nach dem Login kopieren

Perfekt können wir einen Parameter an die Erstellungsmethode übergeben, um sicherzustellen, dass wir beim Erstellen den richtigen Typ festlegen, damit sich unsere Geschäftsregeln nicht beschweren. Aber es so zu schreiben ist etwas umständlich, also lasst uns unsere Fabrik ein wenig umgestalten und eine Methode hinzufügen, um den Status zu ändern:

 declare(strict_types=1);

namespace Database\Factories;

use App\Models\Post;
use App\Publishing\Enums\PostStatus;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition(): array
    {
        $title = $this->faker->sentence();

        return [
            'title' => $title,
            'slug' => Str::slug($title),
            'content' => $this->faker->paragraph(),
            'status' => PostStatus::DRAFT->value,
            'published_at' => null,
        ];
    }

    public function published(): static
    {
        return $this->state(
            fn (array $attributes): array => [
                'status' => PostStatus::PUBLISHED->value,
                'published_at' => now(),
            ],
        );
    }
}
Nach dem Login kopieren

Wir legen einen Standardwert für die Fabrik fest, sodass alle neu erstellten Beiträge Entwürfe sind. Anschließend fügen wir eine Methode hinzu, um den Status auf „Veröffentlichung“ festzulegen, die den korrekten Enum-Wert verwendet und das Veröffentlichungsdatum festlegt – was in einer Testumgebung vorhersehbarer und wiederholbarer ist. Mal sehen, wie unser Test jetzt aussieht:

 it('can update a post', function () {
    $post = Post::factory()->create();

    putJson(
        route('api.posts.update', $post->slug),
        ['content' => 'test content',
    )->assertSuccessful();

    expect(
        $post->refresh()
    )->content->toEqual('test content');
});
Nach dem Login kopieren
Nach dem Login kopieren

Zurück zu einem einfachen Test – wenn wir also mehrere Tests haben, die einen Entwurfsbeitrag erstellen möchten, können sie eine Factory verwenden. Schreiben wir nun einen Test für den veröffentlichten Status, um festzustellen, ob Fehler vorliegen.

 it('returns an error when trying to update a published post', function () {
    $post = Post::factory()->published()->create();

    putJson(
        route('api.posts.update', $post->slug),
        ['content' => 'test content',
    )->assertStatus(Http::UNPROCESSABLE_ENTITY());

    expect(
        $post->refresh()
    )->content->toEqual($post->content);
});
Nach dem Login kopieren

Dieses Mal testen wir, ob wir einen Validierungsfehlerstatus erhalten, wenn wir versuchen, einen veröffentlichten Beitrag zu aktualisieren. Dadurch stellen wir sicher, dass wir unsere Inhalte schützen und bestimmte Arbeitsabläufe in unseren Anwendungen durchsetzen.

Was passiert also, wenn wir auch in der Fabrik bestimmte Inhalte sicherstellen wollen? Bei Bedarf können wir eine weitere Methode hinzufügen, um den Status zu ändern:

 declare(strict_types=1);

namespace Database\Factories;

use App\Models\Post;
use App\Publishing\Enums\PostStatus;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition(): array
    {
        return [
            'title' => $title = $this->faker->sentence(),
            'slug' => Str::slug($title),
            'content' => $this->faker->paragraph(),
            'status' => PostStatus::DRAFT->value,
            'published_at' => null,
        ];
    }

    public function published(): static
    {
        return $this->state(
            fn (array $attributes): array => [
                'status' => PostStatus::PUBLISHED->value,
                'published_at' => now(),
            ],
        );
    }

    public function title(string $title): static
    {
        return $this->state(
            fn (array $attributes): array => [
                'title' => $title,
                'slug' => Str::slug($title),
            ],
        );
    }
}
Nach dem Login kopieren

So können wir innerhalb unserer Tests einen neuen Test erstellen, um sicherzustellen, dass wir den Titel des Beitragsentwurfs über unsere API aktualisieren können:

 it('can update a draft posts title', function () {
    $post = Post::factory()->title('test')->create();

    putJson(
        route('api.posts.update', $post->slug),
        ['title' => 'new title',
    )->assertSuccessful();

    expect(
        $post->refresh()
    )->title->toEqual('new title')->slug->toEqual('new-title');
});
Nach dem Login kopieren

So können wir das tun Verwenden Sie den Werkszustand, um Dinge in unserer Testumgebung zu steuern und uns so viel Kontrolle wie möglich zu geben. Auf diese Weise stellen wir sicher, dass wir stets auf Tests vorbereitet sind oder dass der Status der Anwendung zu einem bestimmten Zeitpunkt gut widergespiegelt wird.

Was sollen wir tun, wenn wir viele Modelle für unsere Tests erstellen müssen? Was sollen wir tun? Die einfache Antwort besteht darin, der Fabrik zu sagen:

it('lists all posts', function () {
    Post::factory(12)->create();

    getJson(
        route('api.posts.index'),
    )->assertOk()->assertJson(fn (AssertableJson $json) =>
        $json->has(12)->etc(),
    );
});
Nach dem Login kopieren

Wir erstellen also 12 neue Beiträge und stellen sicher, dass wir 12 Beiträge zurückerhalten, wenn wir die Indexroute erhalten. Anstatt count an die Factory-Methode zu übergeben, können Sie auch die count-Methode verwenden:

Post::factory()->count(12)->create();
Nach dem Login kopieren

Allerdings möchten wir in unseren Anwendungen manchmal Dinge in einer bestimmten Reihenfolge ausführen. Angenommen, wir möchten, dass der erste Entwurf ein Entwurf ist, der zweite jedoch veröffentlicht wird?

 it('shows the correct status for the posts', function () {
    Post::factory()
        ->count(2)
        ->state(new Sequence(
            ['status' => PostStatus::DRAFT->value],
            ['status' => PostStatus::PUBLISHED->value],
        ))->create();

    getJson(
        route('api.posts.index'),
    )->assertOk()->assertJson(fn (AssertableJson $json) =>
        $json->where('id', 1)
            ->where('status' PostStatus::DRAFT->value)
            ->etc();
    )->assertJson(fn (AssertableJson $json) =>
        $json->where('id', 2)
            ->where('status' PostStatus::PUBLISHED->value)
            ->etc();
    );
});
Nach dem Login kopieren

Wie nutzen Sie Modellfabriken in Ihrer Anwendung? Haben Sie coole Möglichkeiten gefunden, sie zu verwenden? Sag es uns auf Twitter!

Originaladresse: https://laravel-news.com/laravel-model-factories

Übersetzungsadresse: https://learnku.com/laravel/t/70290

[Verwandte Empfehlungen: laravel-Video-Tutorial

Das obige ist der detaillierte Inhalt vonWie verwende ich die Modellfabrik in der Laravel-Anwendung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage