Symfony 5:如何在集成测试中模拟 HttpClientInterface?
Symfony 5: how do I mock HttpClientInterface in integration test?
我有一个控制器端点,它在幕后执行外部 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 本身来处理的。
尝试测试时,您最终可能会像您的情况一样,直接在您的容器中设置模拟 class。
这将抛出您看到的错误。
要解决此错误,请在配置文件夹中的 services.yaml 文件中,在底部添加以下行:
when@test:
services:
_defaults:
public: true
test.Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Contracts\HttpClient\HttpClientInterface'
你在这里做的是告诉 Symfony 在测试期间你将有一个名为 test 的 public 服务。Symfony\Contracts\HttpClient\HttpClientInterface 它是 HTTPClientInterface class 的副本。
现在,在您的测试代码中,您可以执行以下操作:
$response = new MockResponse(null, ['http_code' => 200]);
$client->getContainer()->set('test.Symfony\Contracts\HttpClient\HttpClientInterface', new TraceableHttpClient(new MockHttpClient($response)));
您可以在 service.yaml
旁边创建一个 service_test.yaml
文件并在其中放入以下代码:
services:
_defaults:
public: true
Symfony\Contracts\HttpClient\HttpClientInterface: ~
它使服务 public 用于测试环境并可以对其进行模拟。
我有一个控制器端点,它在幕后执行外部 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 本身来处理的。
尝试测试时,您最终可能会像您的情况一样,直接在您的容器中设置模拟 class。
这将抛出您看到的错误。
要解决此错误,请在配置文件夹中的 services.yaml 文件中,在底部添加以下行:
when@test:
services:
_defaults:
public: true
test.Symfony\Contracts\HttpClient\HttpClientInterface: '@Symfony\Contracts\HttpClient\HttpClientInterface'
你在这里做的是告诉 Symfony 在测试期间你将有一个名为 test 的 public 服务。Symfony\Contracts\HttpClient\HttpClientInterface 它是 HTTPClientInterface class 的副本。
现在,在您的测试代码中,您可以执行以下操作:
$response = new MockResponse(null, ['http_code' => 200]);
$client->getContainer()->set('test.Symfony\Contracts\HttpClient\HttpClientInterface', new TraceableHttpClient(new MockHttpClient($response)));
您可以在 service.yaml
旁边创建一个 service_test.yaml
文件并在其中放入以下代码:
services:
_defaults:
public: true
Symfony\Contracts\HttpClient\HttpClientInterface: ~
它使服务 public 用于测试环境并可以对其进行模拟。