Laravel Mock 应该至少被调用一次但被调用 0 次
Posted
技术标签:
【中文标题】Laravel Mock 应该至少被调用一次但被调用 0 次【英文标题】:Laravel Mock should be called at least once but called 0 times 【发布时间】:2020-03-28 00:23:25 【问题描述】:我有一个工匠命令,它会触发一个名为 PasswordResetJob 的作业,该作业在调用存储库类 OrgRepository 中的方法 forcePasswordReset 时进行迭代,即方法更新用户的表。整个过程运行良好。
现在我正在尝试编写一个 Laravel 测试来模拟 OrgRepository 类并断言 forcePasswordReset 方法至少被调用一次,应该是这样,根据我提供给测试的条件。在测试中,我调用工匠命令来解雇工作; (我正在使用同步队列进行测试)这工作正常,因为作业被调用并且用户的表得到更新,因为我可以直接查看我的数据库更新。 但是,测试失败并出现错误: Mockery\Exception\InvalidCountException : Method forcePasswordReset() from Mockery_2_Repositories_OrgRepository 应该被调用 至少 1 次但调用了 0 次。
测试中的工匠调用是:
Artisan::call('shisiah:implement-org-password-reset');
我曾尝试在此模拟初始化之前和之后进行工匠调用,但我仍然遇到相同的错误。这是测试中的模拟初始化
$this->spy(OrgRepository::class, function ($mock)
$mock->shouldHaveReceived('forcePasswordReset');
);
我错过了什么?我浏览了文档并在 Google 上搜索了几个小时。如果您需要任何其他信息来提供帮助,请告诉我。我正在使用 Laravel 6.0 版
编辑
我将 OrgRepository 类传递给作业类的 handle 方法,如下所示:
public function handle(OrgRepository $repository)
//get orgs
$orgs = Org::where('status', true)->get();
foreach ($orgs as $org)
$repository->forcePasswordReset($org);
【问题讨论】:
仓库是通过ioc容器解析的还是你自己实例化的?您能否添加您在工作中使用 OrgRepository 的方式。 @Remul 我已经更新了问题,请检查 在测试中你在哪里初始化你的间谍?shouldHaveReceived
必须在您的作业运行后调用,而不是在此之前调用,否则您应该使用 shouldReceive
。
@Remul 是的,在测试中,我首先调用触发工作的工匠命令,然后调用间谍
$orgs
是否包含包含某些元素的数组?分配该变量后,您可以发布dd($orgs)
的输出吗?
【参考方案1】:
问题是你在你的作业已经运行之后初始化你的间谍,这意味着在作业期间它将使用真实的类而不是间谍。
你必须在你的测试中做这样的事情:
$spy = $this->spy(OrgRepository::class);
// run your job
$spy->shouldHaveReceived('forcePasswordReset');
我们告诉 laravel 使用 spy 而不是存储库,运行作业,然后断言该方法已被调用。
Jeffrey Way 在this 截屏视频中很好地解释了这一点。
【讨论】:
以上是关于Laravel Mock 应该至少被调用一次但被调用 0 次的主要内容,如果未能解决你的问题,请参考以下文章
如何提取在 2020 年 1 月至少访问过两次但未进行交易的所有 visitor_id 的列表(在他们 1 月的任何一次访问中)