本文小編為大家詳細介紹“Laravel應用程序中怎么使用模型工廠”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Laravel應用程序中怎么使用模型工廠”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
創新互聯公司是一家成都做網站、網站制作,提供網頁設計,網站設計,網站制作,建網站,按需開發,網站開發公司,從2013年開始是互聯行業建設者,服務者。以提升客戶品牌價值為核心業務,全程參與項目的網站策劃設計制作,前端開發,后臺程序制作以及后期項目運營并提出專業建議和思路。
Laravel 模型工廠是你可以在應用程序中進行測試時使用的最佳功能之一。它們提供了一種定義可預測且易于復制的數據的方法,以便你的測試保持一致和可控。
讓我們從一個簡單的例子開始。我們有一個用于寫博客的應用程序,所以很自然地,我們有一個 Post
模型,該模型具有發布、起草或排隊的狀態。讓我們看一下這個例子的 Eloquent 模型:
正如你在此處看到的,我們有一個用于狀態列的 Enum,我們現在將對其進行設計。在這里使用枚舉允許我們利用 PHP 8.1 的特性,而不是純字符串、布爾標志或混亂的數據庫枚舉。 現在,讓我們回到我們在這里討論的主題:模型工廠。一個簡單的工廠看起來很簡單: 所以在我們的測試中,我們現在可以快速調用我們的 post factory 為我們創建一個 post。讓我們看看我們可以如何做到這一點: 一個足夠簡單的測試,但是如果我們的業務規則規定你只能根據帖子類型更新特定列,會發生什么?讓我們重構我們的測試以確保我們可以做到這一點: 完美,我們可以將一個參數傳遞給 create 方法,以確保我們在創建它時設置正確的類型,這樣我們的業務規則就不會抱怨。但是這樣寫有點麻煩,所以讓我們稍微重構一下我們的工廠,添加修改狀態的方法: 我們為工廠設置了默認值,以便所有新創建的帖子都是草稿。然后我們添加一個設置要發布的狀態的方法,它將使用正確的 Enum 值并設置發布日期 - 在測試環境中更具可預測性和可重復性。讓我們看看我們的測試現在是什么樣子: 回到一個簡單的測試——所以如果我們有多個測試想要創建一個草稿帖子,他們可以使用工廠。現在讓我們為發布的狀態編寫一個測試,看看是否有錯誤。 這次我們正在測試當我們嘗試更新已發布的帖子時是否收到驗證錯誤狀態。這可確保我們保護我們的內容并在我們的應用程序中強制執行特定的工作流程。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',
];
}
declare(strict_types=1);
namespace App\Publishing\Enums;
enum PostStatus: string
{
case PUBLISHED = 'published';
case DRAFT = 'draft';
case QUEUED = 'queued';
}
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,
];
}
}
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');
});
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');
});
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(),
],
);
}
}
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');
});
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);
});
那么如果我們還想確保工廠中的特定內容會發生什么呢?我們可以根據需要添加另一種方法來修改狀態:
因此,在我們的測試中,我們可以創建一個新測試,以確保我們可以通過我們的 API 更新草稿帖子標題: 所以我們可以很好地使用工廠狀態來控制我們的測試環境中的東西,給我們盡可能多的控制權。這樣做將確保我們始終如一地準備測試,或者很好地反映特定點的應用程序狀態。 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),
],
);
}
}
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');
});
如果我們需要為我們的測試創建許多模型,我們該怎么辦?我們應該怎么做?簡單的答案是告訴工廠:
所以我們正在創建 12 個新帖子,并確保當我們獲得索引路由時,我們有 12 個帖子返回。除了將 count 傳遞給工廠方法,你還可以使用 count 方法: 但是,在我們的應用程序中,有時我們可能希望以特定順序運行事物。假設我們希望第一個是草稿,但第二個已發布?it('lists all posts', function () {
Post::factory(12)->create();
getJson(
route('api.posts.index'),
)->assertOk()->assertJson(fn (AssertableJson $json) =>
$json->has(12)->etc(),
);
});
Post::factory()->count(12)->create();
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();
);
});
讀到這里,這篇“Laravel應用程序中怎么使用模型工廠”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注創新互聯行業資訊頻道。