php - Symfony 5:如何在集成测试中模拟 HttpClientInterface?
问题描述
我有一个控制器端点,它在引擎盖下执行一个外部 API 请求,我每次运行测试时都无法做到。
我HttpClientInterface
用来提出请求,现在我的想法是用MockHttpClient
. 所以这是我到目前为止所拥有的:
class MyControllerTest extends WebTestCase
{
public function testSomething(): void
{
$client = static::createClient();
$response = new MockResponse(null, ['http_code' => 200]);
$client->getContainer()->set(HttpClientInterface::class, new MockHttpClient($response));
$client->request('GET', '/my-end-point');
self::assertResponseIsSuccessful();
}
}
但它给了我以下错误:
The "Symfony\Contracts\HttpClient\HttpClientInterface" service is private, you cannot replace it
这有点道理。有没有更好的解决方案或如何克服这个问题?
解决方案
在 Symfony 环境中,服务是私有的,但这不是问题,因为您通过依赖注入将它们放入您的控制器、服务等,这意味着是 Symfony 自己负责处理它。
在尝试测试时,您最终可能会像您的情况一样,直接在容器中设置模拟类。
这将抛出您看到的错误。
为了克服这个错误,在位于 config 文件夹中的 services.yaml 文件中,只需在底部添加以下行:
when@test:
services:
_defaults:
public: true
test.Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Contracts\HttpClient\HttpClientInterface'
您在这里所做的是告诉 Symfony,在测试期间您将拥有一个名为 test.Symfony\Contracts\HttpClient\HttpClientInterface 的公共服务,它是 HTTPClientInterface 类的副本。
现在,在您的测试代码中,您可以执行以下操作:
$response = new MockResponse(null, ['http_code' => 200]);
$client->getContainer()->set('test.Symfony\Contracts\HttpClient\HttpClientInterface', new TraceableHttpClient(new MockHttpClient($response)));
推荐阅读
- raspberry-pi - 录制每个通道而不混音
- javascript - 如何用单引号在js函数中传递多个参数
- c++ - 尝试显示矢量元素时终止命令
- c# - 在 Entity Framework Core 中的第二级过滤
- lua - 尝试使用 HumanoidRootPart 索引布尔值
- javascript - React 中的 Fetch 在 url 之前添加 localhost
- java - 在 CoroutineDispatcher 中调用 CoroutineDispatcher 时应用程序冻结
- swift - 如何知道集合视图大纲何时展开?
- java - 使用没有范围的 RxJava 调用协程
- c++ - 如何从缓冲区创建接收器写入器?