php - 在 Laravel 中运行功能测试时如何模拟服务(或服务提供者)?
问题描述
我在 Laravel 中编写了一个小 API,部分是为了学习这个框架。我想我在文档中发现了一个巨大的漏洞,但这可能是因为我不理解“Laravel 方式”来做我想做的事。
我正在编写一个 HTTP API 来列出、创建和删除 Linux 服务器上的系统用户。结构是这样的:
/v1/users
连接的路由GET
,POST
以及DELETE
控制器方法的动词get
,create
和delete
分别。- 控制器
App\Http\Controllers\UserController
实际上并不运行系统调用,这是由 service 完成的App\Services\Users
。 - 服务由服务提供者创建,该服务提供者在延迟的基础上
App\Providers\Server\Users
注册服务。singleton
- 该服务由 Laravel 自动实例化并自动注入到控制器的构造函数中。
好的,所以这一切都有效。我还编写了一些测试代码,如下所示:
public function testGetUsers()
{
$response = $this->json('GET', '/v1/users');
/* @var $response \Illuminate\Http\JsonResponse */
$response
->assertStatus(200)
->assertJson(['ok' => true, ]);
}
这也很好用。但是,这使用了 的正常绑定UserService
,我想在这里放一个虚拟/模拟。
我想我需要将我的更改UserService
为一个接口,这很容易,但我不确定如何告诉底层测试系统我希望它运行我的控制器,但使用非标准服务。在研究这个问题时,我看到App::bind()
Stack Overflow 的答案出现了,但App
在工匠生成的测试中并没有自动出现,所以感觉就像在抓着稻草。
如何实例化一个虚拟服务,然后在测试时将其发送到 Laravel,这样它就不会使用标准的 ServiceProvider 了?
解决方案
显而易见的方法是在setUp()
.
让你自己成为一个新人UserTestCase
(或编辑 Laravel 提供的那个)并添加:
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected function setUp()
{
parent::setUp();
app()->bind(YourService::class, function() { // not a service provider but the target of service provider
return new YourFakeService();
});
}
}
class YourFakeService {} // I personally keep fakes in the test files itself if they are short
在方法中根据环境有条件地注册提供程序(将其放入AppServiceProvider.php或您为此任务指定的任何其他提供程序 - ConditionalLoaderServiceProvider.php或其他)register()
if (app()->environment('testing')) {
app()->register(FakeUserProvider::class);
} else {
app()->register(UserProvider::class);
}
注意:缺点是提供者列表在两个地方,一个在 config/app.php,一个在 AppServiceProvider.php
推荐阅读
- python - 'tensorflowjs_converter' 不是内部或外部命令、可运行程序或批处理文件
- convex-optimization - Q >= 0 的二次函数中等式约束“A x = 0”的拉格朗日松弛
- python - Altair 图表 - 自定义轴格式化程序功能
- mysql - 优化子查询的最佳方法
- json - PostgreSQL 13 - 如何排序递归 JSON 层次结构
- c# - 带有 .net 5 的 Windows 窗体应用程序中出现不需要的标题栏
- javascript - 单击“刷新”按钮时重新加载其他页面
- css - 为什么我的容器与其内容的大小不同?
- javascript - Discord 机器人计算每个用户的特定单词 Discord.js
- linux - 如何编译这个 .c.txt 文件?- Ubuntu