gpt4 book ai didi

php - 在 Laravel 中运行功能测试时如何模拟服务(或 ServiceProvider)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:02:15 24 4
gpt4 key购买 nike

我正在用 Laravel 编写一个小 API,部分目的是为了学习这个框架。我想我在文档中发现了一个漏洞,但这可能是因为我不理解“Laravel 方式”来做我想做的事。

我正在编写一个 HTTP API,用于在 Linux 服务器上列出、创建和删除系统用户等。结构是这样的:

  • /v1/users 的路由将 GETPOSTDELETE 动词连接到 Controller 方法 分别获取创建删除
  • Controller App\Http\Controllers\UserController 实际上并不运行系统调用,它是由服务 App\Services\Users 完成的。
  • 该服务由服务提供者 App\Providers\Server\Users 创建,该服务提供者在延迟的基础上注册该服务的单例
  • 该服务由 Laravel 自动实例化并自动注入(inject)到 Controller 的构造函数中。

好的,所以这一切都有效。我也写了一些测试代码,像这样:

public function testGetUsers()
{
$response = $this->json('GET', '/v1/users');
/* @var $response \Illuminate\Http\JsonResponse */

$response
->assertStatus(200)
->assertJson(['ok' => true, ]);
}

这也很好用。但是,这使用了 UserService 的正常绑定(bind),我想在这里放置一个虚拟/模拟。

我想我需要将我的 UserService 更改为一个接口(interface),这很简单,但我不确定如何告诉底层测试系统我希望它运行我的 Controller ,但是使用非标准服务。在研究这个问题时,我看到 App::bind() 突然出现在 Stack Overflow 的答案中,但是 App 并没有自动出现在 artisan 生成的测试范围内,所以感觉就像抓紧了在吸管上。

如何实例化一个虚拟服务,然后在测试时将其发送给 Laravel,而不是使用标准的 ServiceProvider?

最佳答案

显而易见的方法是在setUp() 中重新绑定(bind)实现。

为自己创建一个新的 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

register() 方法

if (app()->environment('testing')) {
app()->register(FakeUserProvider::class);
} else {
app()->register(UserProvider::class);
}

Note: drawback is that list of providers is on two places one in config/app.php and one in the AppServiceProvider.php

关于php - 在 Laravel 中运行功能测试时如何模拟服务(或 ServiceProvider)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50262576/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com