创建外键对象时,Laravel模型工厂make()绕过create()

创建外键对象时,Laravel模型工厂make()绕过create(),laravel,unit-testing,Laravel,Unit Testing,我有一个客户级工厂 $factory->define(Customer::class, function (Faker $faker) { return [ 'hotel_id' => function() { return factory(\App\Hotel::class)->create()->id; }, 'name' => $faker->name, 'p

我有一个客户级工厂

$factory->define(Customer::class, function (Faker $faker) {
    return [
        'hotel_id' => function() {
            return factory(\App\Hotel::class)->create()->id;
        },
        'name' => $faker->name,
        'phone' => $faker->phoneNumber,
        'email' => $faker->email,
    ];
});
调用factory(Customer:class)->create()工作正常。 但是,如果我想使用factory(Customer:class)->make()在内存中创建Customer对象以传递给单元测试,那么这个工厂将创建一个Hotel对象并保存到我的数据库中

是否有一种模式可以帮助Laravel识别factory make(),并在生成对象时使用不同的方法。就像我调用工厂(Customer:class)->make()一样,它将生成

'name' => $faker->name,
'phone' => $faker->phoneNumber,
'email' => $faker->email,

然后它将创建一个$hotel=factory(hotel:class)->make()并执行$customer->setRelation('hotel',$hotel)

您应该将
hotel\u id
保留在工厂之外
define
并使用after回调

从文件中(我的重点):

工厂回调使用Aftermake和 创建方法之后,并允许您在创建方法之后执行其他任务 制作或创建模型。例如,您可以使用回调来 将其他模型与创建的模型关联起来

例子
$factory->aftermake(应用程序\用户::类,函数($User,$faker){
// ...
});
$factory->afterCreating(应用程序\用户::类,函数($User,$faker){
$user->accounts()->save(工厂(App\Account::class)->make());
});

我已经试过了。另一个问题出现了。由于我的字段不可为null(),当我想将对象插入数据库时,它会抛出SQL冲突(因为我们计划在创建后添加hotel_id)。您的解决方案是什么?您可以在工厂中定义hotel_id=0。。因为它稍后会被after回调覆盖,但这是一个外键,在您编写的原始问题中,您希望在内存中创建Customer::class以将其传递给单元测试。在这种情况下,您不需要填写酒店id。您应该在保留之前指定一家酒店。因此,在内存中创建对象和持久化之间,创建一个Hotel()并附加它。