Factory
建立假資料,同時建立資料的狀態與關聯
通常寫在 Laravel 的程式幾乎都會呼叫資料庫,所幸有提供 Eloquent factories 來建立資料庫的假資料。
測試資料庫有個很重要的特質——每次測試都要是新的。
如果打算做一個測試資料庫,但裡面的資料是既有的資料的話,每次撰寫測試都需要重新理解這個資料庫裡面藏了什麼資料。這無疑會增加寫測試的難度。
測試目標:
class Target
{
public function getTarget(int $id): array
{
$target = Target::with(['categories'])->findOrFail($id);
return [
'id' => $target->id,
'name' => $target->name,
'categories' => $target->categories->map(fn($category) => [
'id' => $category->id,
'name' => $category->name,
])->toArray()
];
}
}
測試範例:
use Illuminate\Foundation\Testing\RefreshDatabase;
class TargetTest extends TestCase
{
use RefreshDatabase;
public function get_target_is_work(): void
{
## arrange
Target::factory()
->state([
'id' => 920,
'name' => '柑仔'
])
->has(Category::factory()->state([
'id' => 123,
'name' => '橘貓'
]))
->create;
## act
$result = $this->app->make(Target::class)->getTarget(920);
## assert
$this->assertEquals([
'id' => 920,
'name' => '柑仔',
'categories' => [
[
'id' => 123,
'name' => '橘貓'
]
]
], $result);
}
}
首先,在測試之前都要使用
RefreshDatabase
trait,會在執行每支測試的時候重置資料庫。接著建立 Target 與 Target 關聯的 Category,這時測試資料庫就會有測試案例上直接寫出來的測試資料。
最後執行測試的時候就會照著測試資料去跑程式
雖然這麼做會讓測試案例變得很長,但可以很清楚資料資料的關聯,以及這些資料與這段程式碼的關係。尤其是當資料的狀態可以影響流程走向時,就可以很細微的將測試覆蓋到每一行程式碼上。
Last updated
Was this helpful?