站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        如何在Laravel應(yīng)用程序中使用模型工廠?

        如何在Laravel應(yīng)用程序中使用模型工廠?下面本篇文章給大家介紹一下在測試中使用 Laravel 模型工程的方法,希望對大家有所幫助!

        如何在Laravel應(yīng)用程序中使用模型工廠?

        Laravel 9 保姆級視頻教程,想學(xué)不會都難!進入學(xué)習(xí)

        Laravel 模型工廠是你可以在應(yīng)用程序中進行測試時使用的最佳功能之一。它們提供了一種定義可預(yù)測且易于復(fù)制的數(shù)據(jù)的方法,以便你的測試保持一致和可控。

        讓我們從一個簡單的例子開始。我們有一個用于寫博客的應(yīng)用程序,所以很自然地,我們有一個 Post 模型,該模型具有發(fā)布、起草或排隊的狀態(tài)。讓我們看一下這個例子的 Eloquent 模型:

        declare(strict_types=1);  namespace AppModels;  use AppPublishingEnumsPostStatus; use IlluminateDatabaseModel;  class Post extends Model {     protected $fillable = [         'title',         'slug',         'content',         'status',         'published_at',     ];      protected $casts = [         'status' => PostStatus::class,         'published_at' => 'datetime',     ]; }
        登錄后復(fù)制

        正如你在此處看到的,我們有一個用于狀態(tài)列的 Enum,我們現(xiàn)在將對其進行設(shè)計。在這里使用枚舉允許我們利用 PHP 8.1 的特性,而不是純字符串、布爾標(biāo)志或混亂的數(shù)據(jù)庫枚舉。

         declare(strict_types=1);  namespace AppPublishingEnums;  enum PostStatus: string {     case PUBLISHED = 'published';     case DRAFT = 'draft';     case QUEUED = 'queued'; }
        登錄后復(fù)制

        現(xiàn)在,讓我們回到我們在這里討論的主題:模型工廠。一個簡單的工廠看起來很簡單:

         declare(strict_types=1);  namespace DatabaseFactories;  use AppModelsPost; use AppPublishingEnumsPostStatus; use IlluminateDatabaseEloquentFactoriesFactory; use IlluminateSupportArr; use IlluminateSupportStr;  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,         ];     } }
        登錄后復(fù)制

        所以在我們的測試中,我們現(xiàn)在可以快速調(diào)用我們的 post factory 為我們創(chuàng)建一個 post。讓我們看看我們可以如何做到這一點:

         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'); });
        登錄后復(fù)制

        登錄后復(fù)制

        一個足夠簡單的測試,但是如果我們的業(yè)務(wù)規(guī)則規(guī)定你只能根據(jù)帖子類型更新特定列,會發(fā)生什么?讓我們重構(gòu)我們的測試以確保我們可以做到這一點:

        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'); });
        登錄后復(fù)制

        完美,我們可以將一個參數(shù)傳遞給 create 方法,以確保我們在創(chuàng)建它時設(shè)置正確的類型,這樣我們的業(yè)務(wù)規(guī)則就不會抱怨。但是這樣寫有點麻煩,所以讓我們稍微重構(gòu)一下我們的工廠,添加修改狀態(tài)的方法:

         declare(strict_types=1);  namespace DatabaseFactories;  use AppModelsPost; use AppPublishingEnumsPostStatus; use IlluminateDatabaseEloquentFactoriesFactory; use IlluminateSupportStr;  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(),             ],         );     } }
        登錄后復(fù)制

        我們?yōu)楣S設(shè)置了默認(rèn)值,以便所有新創(chuàng)建的帖子都是草稿。然后我們添加一個設(shè)置要發(fā)布的狀態(tài)的方法,它將使用正確的 Enum 值并設(shè)置發(fā)布日期 – 在測試環(huán)境中更具可預(yù)測性和可重復(fù)性。讓我們看看我們的測試現(xiàn)在是什么樣子:

         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'); });
        登錄后復(fù)制

        登錄后復(fù)制

        回到一個簡單的測試——所以如果我們有多個測試想要創(chuàng)建一個草稿帖子,他們可以使用工廠?,F(xiàn)在讓我們?yōu)榘l(fā)布的狀態(tài)編寫一個測試,看看是否有錯誤。

         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); });
        登錄后復(fù)制

        這次我們正在測試當(dāng)我們嘗試更新已發(fā)布的帖子時是否收到驗證錯誤狀態(tài)。這可確保我們保護我們的內(nèi)容并在我們的應(yīng)用程序中強制執(zhí)行特定的工作流程。

        那么如果我們還想確保工廠中的特定內(nèi)容會發(fā)生什么呢?我們可以根據(jù)需要添加另一種方法來修改狀態(tài):

         declare(strict_types=1);  namespace DatabaseFactories;  use AppModelsPost; use AppPublishingEnumsPostStatus; use IlluminateDatabaseEloquentFactoriesFactory; use IlluminateSupportStr;  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),             ],         );     } }
        登錄后復(fù)制

        因此,在我們的測試中,我們可以創(chuàng)建一個新測試,以確保我們可以通過我們的 API 更新草稿帖子標(biāo)題:

         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'); });
        登錄后復(fù)制

        所以我們可以很好地使用工廠狀態(tài)來控制我們的測試環(huán)境中的東西,給我們盡可能多的控制權(quán)。這樣做將確保我們始終如一地準(zhǔn)備測試,或者很好地反映特定點的應(yīng)用程序狀態(tài)。

        如果我們需要為我們的測試創(chuàng)建許多模型,我們該怎么辦?我們應(yīng)該怎么做?簡單的答案是告訴工廠:

        it('lists all posts', function () {     Post::factory(12)->create();      getJson(         route('api.posts.index'),     )->assertOk()->assertJson(fn (AssertableJson $json) =>         $json->has(12)->etc(),     ); });
        登錄后復(fù)制

        所以我們正在創(chuàng)建 12 個新帖子,并確保當(dāng)我們獲得索引路由時,我們有 12 個帖子返回。除了將 count 傳遞給工廠方法,你還可以使用 count 方法:

        Post::factory()->count(12)->create();
        登錄后復(fù)制

        但是,在我們的應(yīng)用程序中,有時我們可能希望以特定順序運行事物。假設(shè)我們希望第一個是草稿,但第二個已發(fā)布?

         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();     ); });
        登錄后復(fù)制

        你如何在應(yīng)用程序中使用模型工廠?你有沒有找到任何很酷的方法來使用它們?在 twitter 上告訴我們!

        原文地址:https://laravel-news.com/laravel-model-factories

        譯文地址:https://learnku.com/laravel/t/70290

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 精品国精品国产自在久国产应用男| 亚洲欧美日韩久久精品第一区 | 精品国产_亚洲人成在线高清| 精品无码久久久久久久久久| 国产精品国产三级国产专播| 熟女精品视频一区二区三区| 婷婷久久精品国产| 国产手机在线精品| 91精品国产综合久久四虎久久无码一级 | 少妇伦子伦精品无码STYLES | 色国产精品一区在线观看| 精品国产人成亚洲区| 91精品国产色综久久| 精品国产网红福利在线观看| 久久精品国产亚洲av高清漫画| 亚洲国产精品人人做人人爱| 精品无码国产污污污免费网站国产| 2020最新久久久视精品爱| 国产精品久久久久久福利漫画| 国产精品一区二区av| 无码久久精品国产亚洲Av影片| 亚洲国产精品13p| 亚洲AⅤ永久无码精品AA| 男女男精品视频网站在线观看| 国语自产精品视频| 国产精品午夜免费观看网站| 99精品国产一区二区| 911亚洲精品不卡| 99热热久久这里只有精品68| wwwvr高清亚洲精品二区| 四虎国产精品永久一区| 久久精品男人影院| 久久久国产精品福利免费| 久久91精品国产91久久小草| 国产精品一区二区久久精品| 精品国产污污免费网站| 欧美精品在线一区二区三区| 91不卡在线精品国产| 国产精品免费看久久久香蕉 | 人妻少妇精品中文字幕AV| 久久精品中文无码资源站|