php - Laravel 没有在单元测试中引导 trait/authing 用户
问题描述
我不知道 Laravel 是否无法启动我的模型特征,或者根本没有看到用户在特征中被认证。
当我手动测试我的应用程序时,所有这些代码都可以正常工作,但是当我运行单元测试时,我遇到了一堆错误。
这是我添加的特征App\User
和其他一些模型:
trait HasCompany
{
public static function bootHasCompany()
{
if (auth()->check()) {
static::creating(function ($model) {
$model->company_id = auth()->user()->company_id;
});
static::addGlobalScope('company_id', function (Builder $builder) {
$builder->where('company_id', auth()->user()->company_id);
});
}
}
public function company()
{
return $this->belongsTo('App\Company');
}
}
此 trait 的目的是自动将登录用户添加company_id
到他们创建的任何模型中,并限制他们仅访问他们创建的模型。我应该提到 all的数据库中App\User
有一个company_id
集合。
正如我所说,当我尝试在登录到我的应用程序时创建模型时,一切都很好。该特征完美地工作。然而,单元测试似乎并不关心这个特性。这是一个不起作用的示例测试:
class RoleTest extends TestCase
{
use WithFaker;
public $user;
public function setup()
{
parent::setUp();
$this->user = App\User::create([
'company_id' => $faker->randomNumber(),
'name' => $this->faker->firstName,
'email' => $this->faker->email,
'password' => $this->faker->password,
]);
}
public function tearDown()
{
parent::tearDown();
$this->user->delete();
}
public function testAdd()
{
$response = $this->actingAs($this->user)->json('POST', 'roles/add', [
'_token' => csrf_token(),
'name' => $this->faker->word,
]);
$response->assertStatus(200)->assertJson(['flash' => true]);
}
}
我得到的是 500 响应而不是 200 响应,因为模型应该自动获取company_id
from $this->user
,但事实并非如此。这仅发生在单元测试中。
这是模型代码:
class Role extends Model
{
use HasCompany;
protected $fillable = ['company_id', 'name'];
}
为什么单元测试不能正确引导特征?似乎actingAs
不适用于特征内的授权,或者无法完全启动它的特征。
解决方案
在您的单元测试中,用户模型是在 setup 函数创建用户时首先启动的。那时,没有用户被认证(如后面所见)。因此,auth()->check()
仅在创建用户时发生一次。
我认为不是检查是否经过身份验证(在启动期间),您应该在用户创建期间检查是否经过身份验证。
从 bootHasCompany 中移除if(auth()->check())
并将其添加到 Eloquent 事件闭包中,如下所示:
static::creating(function ($model) {
if(auth()->check())
{
$model->company_id = auth()->user()->company_id;
}
});
static::addGlobalScope('company_id', function (Builder $builder) {
if(auth()->check())
{
$builder->where('company_id', auth()->user()->company_id);
}
});
推荐阅读
- inkcanvas - 手写功能就像 fiinote 手写一样
- android - 在本机反应中发布后崩溃的应用程序?
- flutter - 如何限制 TextSpan 小部件的文本长度
- javascript - 单击“Enter”按钮时提交表单,并进行验证
- flutter - 如何在不改变屏幕/页面的情况下传递数据?
- kubernetes - 是否可以在容器内的 env 中将 application.properties 的内容作为键/值对公开?
- javascript - 使用 node.js 处理来自 aws s3 getobject 的数百万条记录并通过分页将记录返回到前端的最佳方法
- python - Django 连接错误(Oracle 11g 数据库)
- vba - 使用手动干预将单词表转换为文本
- angular - 由于我们在 d3 v3 中具有标注功能,有没有办法在 d3 v5 中自动放置标签而不重叠?