如何在作曲家包开发测试中模拟用户模型?
Posted
技术标签:
【中文标题】如何在作曲家包开发测试中模拟用户模型?【英文标题】:How to mock User model within composer package development tests? 【发布时间】:2020-01-17 01:48:27 【问题描述】:我开始为我们公司创建一个基于 laravel 5.8 的模块化 API 框架,应该使用 composer 包进行扩展。
现在,如果包需要访问基础框架 (App/Models/User
) 中给定的用户模型,我偶然发现了单独测试每个包(当然每个包都有自己的 GIT 项目)的问题。
根据用户模型,例如特定的身份验证模块,自然会有各种包。
不幸的是,测试也变得更加复杂,因为我们使用的是 GraphQL (Lighthouse)。
那么这应该怎么做呢?我尝试使用包含在我的包的测试文件夹中的用户模型来模拟 App/Models/User,但这没有按预期工作:
$this->userMock = \Mockery::mock('CompanyName\\PackageName\\Tests\\User');
$this->app->instance('App\\Models\\User', $this->userMock);
之后,当发布 GraphQL 请求时,解析器方法会引发 Class App\Models\User does not exist
错误。
我对使用 phpunit 进行测试很陌生,所以也许我只是在这里遗漏了一些东西?
编辑: 我刚刚发现显示上面的错误消息是因为在 GraphQL 模式文件中也引用了 User 模型。 所以我有任何解决方案,我猜它必须以某种方式“模拟”整个请求生命周期中不存在的用户模型类......
【问题讨论】:
你是否在 User.php 上检查过你的命名空间。namespace App\Models;
之前 class User
命名空间在主项目中是namespace App\Models;
,但是由于测试存在于(分离的)包中,因此该模型对于测试并不存在,还是我错了?
剂量用户模型在控制器上工作?我认为它不应该存在于测试文件夹中。或者您可以发布您的项目文件夹结构吗?
将包安装到基础项目时一切正常。测试文件夹中的用户类只是我试图解决这个问题,即使它可以工作也不是最好的解决方案。
【参考方案1】:
好吧,我终于解决了我的问题,我猜这在概念上更明智。由于用户模型与我要测试的(核心)包紧密相关,因此我现在已将模型移动到包本身并将其从基础项目中删除。 这样做的好处是“最终用户开发人员”甚至看不到,并且必须处理无论如何都由包处理的用户模型。
现在我可以独立测试包,只需在 README 中添加一行文档即可告知用户必须更改 auth.providers.users.model
值才能让 laravel 使用适当的模型(例如 CompanyName\\PackageName\\Models
)。
如果有其他扩展用户模型的包,他们将不得不依赖核心包(他们应该以任何方式)并且可以扩展模型类并告诉用户再次更新auth.providers.users.model
。这样一来,查看当前使用的用户模型也很安静。
对于 GraphQL / Lighthouse 部分,我已将以下代码添加到包的服务提供者的引导方法中,以使 Lighthouse 自动了解包中的新模型:
$lighthouseModels = config('lighthouse.namespaces.models');
array_push($lighthouseModels, 'CompanyName\\PackageName\\Models');
config([
'lighthouse.namespaces.models' => $lighthouseModels
]);
也可以为每个添加模型的包重复此操作,以便 lighthouse 了解所有这些。
【讨论】:
以上是关于如何在作曲家包开发测试中模拟用户模型?的主要内容,如果未能解决你的问题,请参考以下文章