PSR-18 兼容的 HTTP 模拟库

v0.12.2 2023-10-03 09:45 UTC

This package is auto-updated.

Last update: 2024-09-03 11:37:09 UTC


README

Build Status Coverage Latest stable PHP from Packagist License

pock

易于使用的 HTTP 模拟解决方案,兼容 PSR-18 和 HTTPlug。

项目仍处于早期开发阶段。API 随时间可能会变化,但我将尽量避免引入破坏性更改。您可以在这里找到自动生成的文档或查看示例。模拟构建的 API 可以在这里找到,响应构建的 API(从 PockBuilder::reply 调用返回)可以在这里找到。

示例

模拟 JSON API 路由,使用基本认证,以 JSON 格式回复。

use Pock\Enum\RequestMethod;
use Pock\Enum\RequestScheme;
use Pock\PockBuilder;

$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
    ->matchScheme(RequestScheme::HTTPS)
    ->matchHost('example.com')
    ->matchPath('/api/v1/users')
    ->matchHeaders([
        'Content-Type' => 'application/json',
        'Authorization' => 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
    ])
    ->reply(200)
    ->withHeader('Content-Type', 'application/json')
    ->withJson([
        [
            'name' => 'John Doe',
            'username' => 'john',
            'email' => '[email protected]'
        ],
        [
            'name' => 'Jane Doe',
            'username' => 'jane',
            'email' => '[email protected]'
        ],
    ]);

// Pass PSR-18 compatible client to the API client.
$client = new MysteriousApiClient($builder->getClient());
$client->setCredentials('username', 'password');

// Receive mock response.
$response = $client->getUsers();

相同的模拟,但使用模型!此外,代码本身也稍微短一些。

use Pock\Enum\RequestMethod;
use Pock\PockBuilder;

$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
    ->matchUri('https://example.com/api/v1/users')
    ->matchHeaders([
        'Content-Type' => 'application/json',
        'Authorization' => 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
    ])
    ->reply(200)
    ->withHeader('Content-Type', 'application/json')
    ->withJson([
        // We're assuming here that MysteriousUser's constructor can receive an initial values.
        new MysteriousUser('John Doe', 'john', '[email protected]'),
        new MysteriousUser('Jane Doe', 'jane', '[email protected]'),
    ]);

// Pass PSR-18 compatible client to the API client.
$client = new MysteriousApiClient($builder->getClient());
$client->setCredentials('username', 'password');

// Receive mock response.
$response = $client->getUsers();

由于 pock 可以在底层使用第三方序列化器,因此可以使用 DTO 模拟响应。

序列化器支持

pock 默认支持 JMS 序列化器和 Symfony 序列化器。可用的序列化器将自动实例化。它将用于序列化模拟中的请求和响应,这意味着您可以实际将整个 DTO 传递到相应的函数中(例如,将 matchJsonBody 作为断言或 withJsonBody 生成响应体)。

默认情况下,JMS 序列化器比 Symfony 序列化器具有更高的优先级。如果您想在运行测试之前(bootstrap.php)覆盖默认行为,可以使用以下方法。

use Pock\Factory\JsonSerializerFactory;
use Pock\Factory\XmlSerializerFactory;
use Pock\Serializer\SymfonySerializerAdapter;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

$encoders = [new XmlEncoder(), new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new SymfonySerializerAdapter(new Serializer($normalizers, $encoders));

JsonSerializerFactory::setSerializer($serializer);
XmlSerializerFactory::setSerializer($serializer);

要使用不受支持的序列化器,您应该创建一个实现 Pock\Serializer\SerializerInterface 的适配器。

迈向稳定之路

  • at(N) - 仅在第 N 次调用时执行模拟。
  • always() - 总是执行此模拟(删除模拟过期时间)。
  • UniversalMockException 分离成几个异常(PockClientExceptionPockNetworkException 等)。
  • 添加更轻松抛出前述列表中异常的方法。
  • replyWithCallback - 使用指定的回调回复。
  • replyWithFactory - 使用指定的响应工厂(提供相应的接口)回复。
  • 使用 DOMDocument 比较 XML 主体,如果出现问题,则回退到文本比较。
  • 正则表达式匹配器用于主体、查询、URI 和路径。
  • 表单数据主体匹配器(部分和精确)
  • 多部分表单主体匹配器(类似于回调匹配器,但将主体解析为多部分表单数据)
  • 破坏性更改:将序列化器装饰器重命名为序列化器适配器。
  • 模拟请求的真实网络响应。
  • 支持 symfony/http-client
  • 记录一切(如果可行,附带示例)。