Laravel 8+ 中直接调用模型的 factory() 方法需先启用 HasFactory Trait,否则抛出 BadMethodCallException;User::factory()->create() 自动生成并入库记录,count() 指定数量,for() 处理关联,state() 覆盖字段值。

在 Laravel 8+ 的测试中,直接调用 Eloquent 模型的静态 factory() 方法能跳过手动实例化工厂类、避免命名空间路径错误、绕开自动发现失败风险,让测试数据生成一步到位——你不再需要写 UserFactory::new()->create(),只需 User::factory()->create() 就能立刻拿到已入库的模型实例。
确认模型已启用 HasFactory Trait
打开你的模型文件(如 app/Models/User.php),检查是否已引入并使用 Illuminate\Database\Eloquent\Factories\HasFactory trait:
若未使用,添加 use Illuminate\Database\Eloquent\Factories\HasFactory; 并在 class 定义中加入 use HasFactory;。这一步【不可跳过】,否则调用 User::factory() 会抛出 BadMethodCallException:Call to undefined method App\Models\User::factory()。
trait 是工厂自动绑定的前提,没有它,框架根本不知道该找哪个工厂类。
创建一条带默认字段的记录
在 PHPUnit 测试方法或 Tinker 中执行:
User::factory()->create();
这行代码会自动定位 database/factories/UserFactory.php,调用其 definition() 方法生成数据,并执行 save() 写入数据库,返回一个完整的 User 实例。
注意:不要加括号写成 User::factory()->create()(),也不要漏掉 create() —— 【只调用 factory() 不会入库】,它返回的是工厂实例,不是模型。
批量生成并指定数量
使用 count() 明确声明条数:
第一步:User::factory()->count(3)->create();
第二步:结果返回 Illuminate\Database\Eloquent\Collection,含 3 个已保存的 User 对象。
第三步:若误写为 User::factory()->create(3),Laravel 会忽略参数,仍只创建 1 条——这是旧版写法残留导致的静默失败,务必用 count()。
关联其他模型并自动处理外键
方法一:关联已存在的模型
User::factory()->for(Post::factory()->create())->create();
方法二:关联新生成的模型(推荐)
User::factory()->for(Post::factory())->create();
区别在于:方法二中 for() 参数是工厂实例,框架会先创建 Post,再把它的 id 填入 User 的 post_id 字段;方法一若 Post 尚未入库,外键会为 null,触发数据库约束报错。
覆盖字段值并保留其余默认逻辑
用 state() 注入补丁字段:
User::factory()->state(['email' => 'admin@test.com', 'is_active' => true])->create();
这不会影响 name、password 等其他字段的 faker 生成规则,只替换指定键。state() 可链式调用多次,但重复 key 以最后一次为准。


















