我有一个 Eloquent
模型,其中在模型的 boot()
方法中定义了一些观察者方法。这是非常简单的逻辑 - 我使用 creating()
静态方法来为属性定义默认值,如果在调用 Model::create([...])
时未定义该属性。
protected static function boot()
{
parent::boot();
static::creating(function (Content $content) {
static::setDefaultValues($content);
});
}
protected static function setDefaultValues(Content $content)
{
if ( ! $content->published_at) {
$content->published_at = Carbon::now();
}
}
通过浏览器或使用
artisan tinker
控制台或数据库seeder,应用程序可以正常工作。
但是,当我尝试使用相同的数据库填充逻辑通过artisan命令引导测试数据库时,在运行测试用例时会抛出异常,称特定属性不能为空。经过一些研究和挖掘Laravel代码,我发现事件分派器应该正常工作,因为我没有模拟任何事件也没有使用withoutEvents()
助手。
此外,全局作用域在测试环境中似乎不适用。
我在几个关键点上放置了var_dumps(在调用creating()
后立即,在Eloquent\Model
类中的save()
方法内部以及在模型事件触发后),以检查属性并注意到观察者方法正在执行,但效果就像模型实例没有通过引用传递给事件处理程序,而是被克隆了。相同的代码在开发环境中可以正常运行,但在测试环境中会失败。
有人遇到过这样的问题吗?我真的不知道该怎么办,请给予任何建议。
值得一提的是,我在开发中使用MySQL,并尝试在SQLite数据库中运行测试以便于使用。测试是使用Laravel的开箱即用的PHPUnit测试设置运行的。