目前我正在测试 Symfony2 中的一些服务,并尝试使用 Guzzle MockPlugin 来控制 CURL 响应。使用 Symfony 版本 2.3.8。我遇到了一个有趣的行为,但我不确定这是否是 Symfony2 的错误。
我在 services.yml 中有这些服务:
lookup_service_client:
class: FOO
public: false
factory_service: lookup_client_builder
factory_method: build
lookup_repository_auth_type:
class: AuthType
arguments: ["@lookup_service_client"]
lookup_repository_cancel_reason:
class: CancelReason
arguments: ["@lookup_service_client"]
payment_service_client:
class: FOO
public: false
factory_service: payment_client_builder
factory_method: build
payment_repository:
class: Payment
arguments: ["@payment_service_client"]
类的名称并不重要。您可以看到“lookup_service_client”和“lookup_service_client”都是私有服务。
我有一个测试类,它扩展了 Symfony\Bundle\FrameworkBundle\Test\WebTestCase。在一项测试中我需要做类似的事情:
$lookup = $this->client->getContainer()->get('lookup_service_client');
$payment = $this->client->getContainer()->get('payment_service_client');
我预计,将这些服务设置为 PRIVATE 不会让我在测试中从容器中检索服务,但实际结果是:
$lookup = $this->client->getContainer()->get('lookup_service_client'); => returns the service instance
$payment = $this->client->getContainer()->get('payment_service_client'); => returns an exception saying: "You have requested a non-existent service"
这两个 service_client 服务之间的唯一区别在于,“lookup_service_client”被注入到其他几个服务中,而“ payment_service_client”仅被注入到其他一项服务中。
所以,问题是:
为什么我可以从容器“lookup_service_client”中检索,因为我已将其设置为私有?
为什么我可以检索“lookup_service_client”,但无法检索“ payment_service_client”,因为唯一的区别如上面所示?
我能访问私服是Symfony2的bug吗?
Symfony 4.1 中对此有一些新的变化:
在 Symfony 4.1 中,我们做了同样的事情,现在测试允许默认获取私有服务。
实际上,基于 WebTestCase 和 KernelTestCase 的测试现在可以通过 $client->getContainer() 或允许获取未删除的私有服务的 static::$container 属性访问特殊容器。
您可以在中阅读更多相关信息新闻帖子 https://symfony.com/blog/new-in-symfony-4-1-simpler-service-testing.
虽然这不是一个错误,但它绝对是违反直觉的。这manual http://symfony.com/doc/current/service_container/alias_private.html具体说:
现在该服务是私有的,您不应该获取该服务
直接从容器中:
$container->get('foo');
这可能有效,也可能无效,具体取决于容器的优化方式
服务实例化,即使在它工作的情况下,也是
已弃用。简单地说:如果您这样做,则可以将服务标记为私有
不想直接从您的代码访问它。
这就是为什么核心团队决定使这种行为更加一致和直观 http://symfony.com/blog/new-in-symfony-3-2-improved-private-services在 Symfony 4 中:
Symfony 3.2 中不推荐使用 Container::set() 方法设置或取消设置私有服务,并且在 4.0 中不再支持;
在 Symfony 4.0 中,使用 Container::has() 检查私有服务是否存在将始终返回 false;
Symfony 3.2 中不推荐使用 Container::get() 方法请求私有服务,并且在 4.0 中不再返回服务。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)