使用 phpunit 时,Eloquent Query Scope 返回 Builder 而不是 Model

Posted

技术标签:

【中文标题】使用 phpunit 时,Eloquent Query Scope 返回 Builder 而不是 Model【英文标题】:Eloquent Query Scope return Builder instead of Model when using phpunit 【发布时间】:2016-12-21 10:15:24 【问题描述】:

我有以下代码

$user = User::findByAccountCode($transaction->account_code);

当我在 phpunit 上执行此代码时,它会返回一个 Illuminate\Database\Eloquent\Builder 的实例,而不是 User Model。

这里是 findByAccountCode 的代码

public function scopeFindByAccountCode($query,$account_code)


   return $query->where('account_code', $account_code)->first();


我的应用程序出现以下错误

ErrorException:参数 1 传递给 aunicaj\Libraries\MarkupRepository::user() 必须是 aunicaj\Models\User,Illuminate\Database\Eloquent\Builder 的实例 给定

当我使用浏览器时,它工作正常,但在 phpunit 上却不行。谢谢

【问题讨论】:

【参考方案1】:

您使用查询范围不正确。他们不应该获取任何记录(这就是您对 first() 的调用所做的事情) - 他们只被允许通过添加/删除约束来更新查询。

替换

public function scopeFindByAccountCode($query,$account_code)
  return $query->where('account_code', $account_code)->first();

public function scopeFindByAccountCode($query,$account_code)
  return $query->where('account_code', $account_code);

并在任何地方使用它,如下所示:

$user = User::findByAccountCode($transaction->account_code)->first();

如果你想在你的 User 方法中有一个方法可以返回给定帐户代码的用户,请随意创建它,但不要以 scope,例如:

public static function findByAccountCode($account_code)
  return static::where('account_code', $account_code)->first();

这样您的代码将按照您的意愿运行 - 调用以下命令来获取单个用户:

$user = User::findByAccountCode($transaction->account_code);

【讨论】:

我认为您的意思是您的静态方法示例 public static function scopeFindByAccountCode 被命名为 public static function findByAccountCode 对吧?【参考方案2】:

我的问题解决了原来我的工厂方法在我的测试中正在使用

factory(User::class)->make() 

应该是

factory(User::class)->create()

【讨论】:

以上是关于使用 phpunit 时,Eloquent Query Scope 返回 Builder 而不是 Model的主要内容,如果未能解决你的问题,请参考以下文章

在 PHPUnit 中调用路由时如何在 Laravel 8 中模拟 Eloquent 模型

如何用 phpunit 模拟 Laravel Eloquent 模型?

如何仅在 phpunit 测试中更改硬编码的 Eloquent $connection?

测试新模型时找不到 Eloquent 类

Mockery 无法使用 Eloquent 模型填充方法创建部分模拟

为啥 Laravel PHPUnit 内存测试会播种我的主数据库?