Класс MockHttpClient
Класс MockHttpClient используется в тестах
для имитации HTTP-запросов. Он реализует интерфейс
HttpClientInterface и позволяет подменить
реальный клиент так, что запросы не уходят в сеть,
а возвращается заранее подготовленный ответ.
Первым параметром в конструктор передаётся
ответ, фабрика ответов или массив ответов.
Каждый ответ - это объект MockResponse
или ResponseInterface.
Синтаксис
<?php
use SymfonyComponentHttpClientMockHttpClient;
use SymfonyComponentHttpClientResponseMockResponse;
$client = new MockHttpClient($response);
?>
Пример
Давайте создадим мок-клиент с одним ответом и выполним через него запрос:
<?php
namespace AppService;
use SymfonyComponentHttpClientMockHttpClient;
use SymfonyComponentHttpClientResponseMockResponse;
class ArticleService
{
public function fetchTitle(): string
{
$client = new MockHttpClient(
new MockResponse('hello')
);
$res = $client->request('GET', 'https://example.com/api/article');
return $res->getContent();
}
}
?>
Результат выполнения кода:
"hello"
Пример
Давайте передадим фабрику, которая формирует ответ в зависимости от запроса:
<?php
namespace AppService;
use SymfonyComponentHttpClientMockHttpClient;
use SymfonyComponentHttpClientResponseMockResponse;
class ArticleService
{
public function fetchData(): string
{
$client = new MockHttpClient(
function (string $method, string $url) {
if (str_contains($url, 'user')) {
return new MockResponse('user');
}
return new MockResponse('article');
}
);
$res = $client->request('GET', 'https://example.com/api/user');
return $res->getContent();
}
}
?>
Результат выполнения кода:
"user"
Пример
Давайте зададим массив ответов, которые будут возвращаться по очереди при каждом запросе:
<?php
namespace AppService;
use SymfonyComponentHttpClientMockHttpClient;
use SymfonyComponentHttpClientResponseMockResponse;
class ArticleService
{
public function fetchAll(): array
{
$client = new MockHttpClient([
new MockResponse('article'),
new MockResponse('user'),
new MockResponse('abcde'),
]);
$res = [];
$res[] = $client->request('GET', 'https://example.com/1')->getContent();
$res[] = $client->request('GET', 'https://example.com/2')->getContent();
$res[] = $client->request('GET', 'https://example.com/3')->getContent();
return $res;
}
}
?>
Результат выполнения кода:
["article", "user", "abcde"]
Пример
Давайте подменим HTTP-клиент в тесте
с помощью MockHttpClient
и проверим ответ:
<?php
namespace AppTestsService;
use AppServiceArticleService;
use PHPUnitFrameworkTestCase;
use SymfonyComponentHttpClientMockHttpClient;
use SymfonyComponentHttpClientResponseMockResponse;
class ArticleServiceTest extends TestCase
{
public function testFetchTitle(): void
{
$client = new MockHttpClient(
new MockResponse('article')
);
$service = new ArticleService($client);
$res = $service->fetchTitle();
$this->assertSame('article', $res);
}
}
?>
Результат выполнения теста:
php bin/phpunit tests/Service/ArticleServiceTest.php
Смотрите также
-
класс
MockResponse,
который задаёт ответ для мок-клиента -
класс
WebTestCase,
который используется для функциональных тестов -
метод
createClient,
который создаёт тестовый клиент -
метод
loginUser,
который авторизует пользователя в тесте