作者:虽虽___Hui | 来源:互联网 | 2022-12-17 20:05
我正在Laravel中编写一个小API,部分原因是为了学习这个框架.我想我已经在文档中发现了一个漏洞,但这可能是因为我不理解"Laravel方式"来做我想做的事情.
我正在编写一个HTTP API,以便在Linux服务器上列出,创建和删除系统用户.结构如下:
路线/v1/users
连接GET
,POST
和DELETE
动词到控制器的方法get
,create
和delete
分别.
控制器App\Http\Controllers\UserController
实际上不会运行系统调用,这是由服务完成的App\Services\Users
.
该服务由ServiceProvider创建,该服务提供者在延迟的基础上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?
1> Kyslik..:
显而易见的方法是重新绑定实现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中的一个位置