fansipan / mock-client

PSR-18 模拟 HTTP 客户端

1.1.1 2024-08-29 16:10 UTC

This package is auto-updated.

Last update: 2024-08-29 16:13:24 UTC


README

Latest Version on Packagist Github Actions Codecov Total Downloads Software License

Fansipan 模拟 HTTP 客户端是 PSR-18 客户端 实现,它提供了发送带有模拟响应的测试请求的能力。

MockClient 接受 Psr\Http\Message\ResponseInterface,当它用于请求时,将返回一个模拟响应,而无需向网络发送真实请求。这可以帮助大量加快测试速度,并可以帮助您测试应用程序针对不同的 API 响应场景,如 404 错误或 500 错误。

安装

您可以通过 composer 安装此包

composer require fansipan/mock-client

使用方法

创建模拟客户端

use Fansipan\Mock\MockClient;

$client = new MockClient();
$response = $client->sendRequest($request);

默认情况下,MockClient 将始终返回 200 - OK 状态码和空主体。如果您想返回不同的响应,请创建一个 Psr\Http\Message\ResponseInterface 实例,并将其作为构造函数参数传递。您可以使用 MockResponse 快速创建一个模拟响应。

use Fansipan\Mock\MockClient;
use Fansipan\Mock\MockResponse;

$client = new MockClient(MockResponse::create('', 500));

模拟响应

MockResponse 类用于创建模拟响应。它可以接受主体、状态和头信息。这些属性将在模拟响应中填充。响应主体接受一个数组作为 JSON 主体或普通字符串以模拟其他响应,如 XML。

use Fansipan\Mock\MockResponse;

MockResponse::create(['name' => 'John', 'age' => 30], 201, ['X-Custom-Header' => 'foo']);

如果您的主体是数组,则无需添加 ['Content-Type' => 'application/json'] 头信息。

如果您有测试数据并且不想手动创建响应,您还可以使用 fixture 方法创建响应。

use Fansipan\Mock\MockResponse;

MockResponse::fixture(__DIR__.'/fixtures/user.json');

如果您的测试数据是 JSON 或 XML 文件,则无需手动添加 Content-Type 头信息。

模拟响应序列

序列模拟允许您按特定顺序定义多个模拟响应。它将拉出序列中的下一个响应,并将其从序列中删除。每个响应只能消费一次。当响应序列中的所有响应都被消费后,任何进一步的请求都将导致响应序列抛出异常。

use Fansipan\Mock\MockClient;
use Fansipan\Mock\MockResponse;

$client = new MockClient([
    MockResponse::make(['name' => 'foo'], 200),
    MockResponse::make(['name' => 'bar'], 201),
    MockResponse::make(['error' => 'Server Error'], 500),
]);

$client->sendRequest($firstRequest); // Will return with `['name' => 'foo']` and status `200`
$client->sendRequest($secondRequest); // Will return with `['name' => 'bar']` and status `200`
$client->sendRequest($thirdRequest); // Will return with `['error' => 'Server Error']` and status `500`

模拟特定 URL

或者,您可以使用 ScopingMockClient 并将一个数组传递给构造函数参数。数组的键应代表您想要模拟的 URL 模式及其关联的响应。可以使用 * 字符作为通配符。对未模拟的 URL 发出的任何请求都将实际执行。

use Fansipan\Mock\MockResponse;
use Fansipan\Mock\ScopingMockClient;

new ScopingMockClient([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => MockResponse::create(['foo' => 'bar'], 200),

    // Stub a string response for Google endpoints...
    'google.com/*' => MockResponse::create('Hello World', 200, $headers),

    // Stub a string response for all other endpoints...
    '*' => MockResponse::create('Hello World', 200, $headers),
]);

序列模拟 也适用于 ScopingMockClient

use Fansipan\Mock\MockResponse;
use Fansipan\Mock\ScopingMockClient;

new ScopingMockClient([
    // Stub sequence JSON responses for GitHub endpoints...
    'github.com/*' => [
        MockResponse::create(['foo' => 'bar']),
        MockResponse::create(['error' => 'Server Error'], 500),
    ],

    // Stub sequence responses for Google endpoints...
    'google.com/*' => [
        MockResponse::create('Hello World', 200, $headers),
        MockResponse::create(['baz' => 'qux']),
    ],
]);

添加期望

当使用模拟响应时,能够检查是否发送了特定的请求以及带有正确的数据和头信息非常重要。 MockClient & ScopingMockClient 为您提供了向测试中添加期望的多种方式。

可用的期望

  • assertSent
  • assetNotSend
  • assertNothingSent
  • assertSentCount

assertSent / assertNotSent 是两个最强大的期望方法。它们可以接受 URL 模式,甚至是一个闭包,在其中您可以定义请求/响应是否是您期望的。

use Fansipan\Mock\MockClient;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

$client = new MockClient();

$request = $requestFactory->createRequest('GET', 'http://example.com/users/1');
$client->sendRequest($request);

$client->assertSent('users/*');

$client->assertSent(function (RequestInterface $request, ResponseInterface $response): bool {
    return $request->getMethod() === 'GET'
        && (string) $request->getUri() === 'http://example.com/users/1'
        && $response->getStatusCode() === 200;
});

测试

composer test

更新日志

请参阅 更新日志 以获取有关最近更改的更多信息。

贡献

请参阅 CONTRIBUTINGCODE_OF_CONDUCT 以获取详细信息。

安全性

如果您发现任何与安全相关的问题,请通过电子邮件 [email protected] 而不是使用问题跟踪器。

致谢

许可证

MIT 许可证 (MIT)。请参阅 许可证文件 以获取更多信息。