【问题标题】:How to mock a many-to-many relationship in Laravel unit tests如何在 Laravel 单元测试中模拟多对多关系
【发布时间】:2019-03-27 20:32:46
【问题描述】:

我有以下创建多对多关系的表、用户、角色和角色用户。

在我的 UserFactory 中创建用户时,我为他们分配了“用户”的基本角色,如下所示:

$factory->afterCreating(User::class, function ($user, $faker){
    $roles = Role::where('name', 'user')->get();
    $user->roles()->sync($roles->pluck('id')->toArray());
});

然后在我的单元测试中,我可以测试用户在尝试访问管理页面时是否被 302 重定向:

$this->actingAs(factory(\App\User::class)->make());

$request = Request::create('/admin', 'GET');

$middleware = new AccessAdmin;
$response = $middleware->handle($request, function () {});

$this->assertEquals($response->getStatusCode(), 302);

这按预期工作,但问题是使用管理员用户测试相反的情况,因为我不确定如何模拟关系数据。我尝试过创建用户,然后像这样附加角色:

$user = factory(\App\User::class)->make();
$roles = Role::where('name', 'admin')->get();
$user->roles()->sync($roles->pluck('id')->toArray());

这给了我以下错误:

PDOException:SQLSTATE[23000]:完整性约束违规:1048 列“user_id”不能为空

这是正确的,因为用户从未在数据库中创建,因此用户没有 ID。

如何模拟用户/角色关系?

【问题讨论】:

  • 您可以发布您的User 模型吗?您是否将roles 定义为belongsToMany 关系?如果是这样,它应该寻找像 role_user_role_id_foreign 这样的外键

标签: laravel unit-testing laravel-5 eloquent


【解决方案1】:

您确定要模拟这种关系吗? 相反,我建议在您的测试文件中使用 DatabaseTransactions 特征,并为您的工厂使用 create() 方法而不是 make()。

use DatabaseTransactions;

....

$user = factory(\App\User::class)->create();

【讨论】:

  • 我不知道交易特征。测试运行后回滚会改变吗?
  • 是的。副作用是增加表中的自动增量值。但在大多数情况下,这无关紧要。
  • 你知道这个特征在什么包下吗?我需要将它带入我的测试,因为它没有找到 PHP Fatal error: Trait 'Tests\Unit\DatabaseTransactions' not found in
猜你喜欢
  • 1970-01-01
  • 2019-12-11
  • 2014-09-19
  • 2019-12-14
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
相关资源
最近更新 更多