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!
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', ]; }
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'; }
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, ]; } }
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'); });
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'); });
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(), ], ); } }
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'); });
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); });
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), ], ); } }
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'); });
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(), ); });
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();
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(); ); });
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!