在 Laravel 中运行功能测试时如何模拟服务(或服务提供者)?
问题描述
我正在 Laravel 中编写一个小型 API,部分是为了学习这个框架.我想我在文档中发现了一个巨大的漏洞,但这可能是因为我不理解Laravel 方式"来做我想做的事.
我正在编写一个 HTTP API,其中包括列出、创建和删除 Linux 服务器上的系统用户.结构是这样的:
- 到
/v1/users
的路由将GET
、POST
和DELETE
动词连接到控制器方法分别获取
、create
和delete
. - 控制器
AppHttpControllersUserController
并不实际运行系统调用,这是由服务AppServicesUsers
完成的. - 服务由 ServiceProvider
AppProvidersServerUsers
创建,该服务提供者在延迟的基础上注册服务的singleton
. - 服务由 Laravel 自动实例化并自动注入到控制器的构造函数中.
好的,所以这一切都有效.我也写了一些测试代码,像这样:
这也很好用.但是,这使用了 UserService
的普通绑定,我想在这里放一个 dummy/mock.
我想我需要将我的 UserService
更改为一个接口,这很容易,但我不确定如何告诉底层测试系统我希望它运行我的控制器,但是使用非标准服务.我在研究此问题时看到 App::bind()
出现在 Stack Overflow 的答案中,但 App
在工匠生成的测试中不会自动出现在范围内,所以感觉就像在抓紧在稻草上.
如何实例化一个虚拟服务,然后在测试时将其发送到 Laravel,这样它就不会使用标准的 ServiceProvider 来代替?
显而易见的方法是在 setUp()
中重新绑定实现.
让你自己成为一个新的 UserTestCase
(或者编辑 Laravel 提供的那个)并添加:
<小时>
在 register()
方法
<块引用>
注意:缺点是提供者的 list 位于两个位置,一个在 config/app.php,一个在 AppServiceProvider.php
I'm writing a small API in Laravel, partly for the purposes of learning this framework. I think I have spotted a gaping hole in the docs, but it may be due to my not understanding the "Laravel way" to do what I want.
I am writing an HTTP API to, amongst other things, list, create and delete system users on a Linux server. The structure is like so:
- Routes to
/v1/users
connectGET
,POST
andDELETE
verbs to controller methodsget
,create
anddelete
respectively. - The controller
AppHttpControllersUserController
does not actually run system calls, that is done by a serviceAppServicesUsers
. - The service is created by a ServiceProvider
AppProvidersServerUsers
that registers asingleton
of the service on a deferred basis. - The service is instantiated by Laravel automatically and auto-injected into the controller's constructor.
OK, so this all works. I have also written some test code, like so:
This also works fine. However, this uses the normal bindings for the UserService
, and I want to put a dummy/mock in here instead.
I think I need to change my UserService
to an interface, which is easy, but I am not sure how to tell the underlying test system that I want it to run my controller, but with a non-standard service. I see App::bind()
cropping up in Stack Overflow answers when researching this, but App
is not automatically in scope in artisan-generated tests, so it feels like clutching at straws.
How can I instantiate a dummy service and then send it to Laravel when testing, so it does not use the standard ServiceProvider instead?
The obvious way is to re-bind the implementation in setUp()
.
Make your self a new UserTestCase
(or edit the one provided by Laravel) and add:
Register providers conditionally based on environment (put this in AppServiceProvider.php or any other provider that you designate for this task - ConditionalLoaderServiceProvider.php or whatever) in register()
method
Note: drawback is that list of providers is on two places one in config/app.php and one in the AppServiceProvider.php
这篇关于在 Laravel 中运行功能测试时如何模拟服务(或服务提供者)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!