Фабрики Laravel автоматично створюють пов’язані моделі, коли визначені відносини, але це може призвести до створення зайвих записів у базі даних під час тестування. Метод dontExpandRelationshipsByDefault() контролює, чи фабрики автоматично ініціюють батьківські зв’язки.
Фабрики часто створюють каскад пов’язаних моделей, хоча вам потрібна лише основна модель для тесту. Це призводить до зайвих записів у базі даних, що уповільнює виконання тестів і ускладнює їх ізоляцію.
use App\Models\OrderItem;
use Database\Factories\OrderItemFactory;
public function test_price_calculation(): void
{
OrderItemFactory::dontExpandRelationshipsByDefault();
$item = OrderItem::factory()->make([
'quantity' => 2,
'unit_price' => 15.50,
'order_id' => 999,
]);
$this->assertEquals(31.00, $item->calculateTotal());
}
Цей тест перевіряє логіку розрахунку ціни без створення записів Order, Product або Customer. Фабрика генерує лише необхідний екземпляр OrderItem для перевірки.
Тестування колекцій з вимкненим розширенням зв’язків дозволяє зосередитися на перевірюваній логіці:
use App\Models\Subscription;
use Database\Factories\SubscriptionFactory;
public function test_active_subscriptions_filter(): void
{
SubscriptionFactory::dontExpandRelationshipsByDefault();
$subscriptions = collect([
Subscription::factory()->make(['status' => 'active', 'plan_id' => 1]),
Subscription::factory()->make(['status' => 'cancelled', 'plan_id' => 2]),
Subscription::factory()->make(['status' => 'active', 'plan_id' => 1]),
]);
$active = $subscriptions->filter(fn($sub) => $sub->isActive());
$this->assertCount(2, $active);
}
Допоміжний метод відновлює поведінку за замовчуванням:
SubscriptionFactory::expandRelationshipsByDefault();
Ви можете перемикати це налаштування в тестовій сукупності за необхідності. Коли розширення відключене, ви все ще можете створювати конкретні зв’язки за допомогою методів фабрики, якщо це потрібно.
Для тестування прав, де потрібні певні комбінації атрибутів без накладних витрат на записи користувача і компанії:
use App\Models\Permission;
use Database\Factories\PermissionFactory;
public function test_permission_scope(): void
{
PermissionFactory::dontExpandRelationshipsByDefault();
$permissions = collect([
Permission::factory()->make([
'type' => 'read',
'resource_id' => 100,
'user_id' => 5,
]),
Permission::factory()->make([
'type' => 'write',
'resource_id' => 100,
'user_id' => 5,
]),
Permission::factory()->make([
'type' => 'read',
'resource_id' => 200,
'user_id' => 5,
]),
]);
$writePermissions = $permissions->where('type', 'write');
$this->assertCount(1, $writePermissions);
}
Такий підхід дозволяє створювати тестові дані, які точно відповідають вашим потребам, без генерації пов’язаних записів, що не є частиною тестового сценарію. Тести виконуються швидше, а стан бази даних залишається передбачуваним між тестуваннями.