gromatics/http-fixtures 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

gromatics/http-fixtures

Composer 安装命令:

composer require gromatics/http-fixtures

包简介

A Laravel package that generates fake JSON responses for HTTP testing using Http::fake(). It simplifies the creation of mock HTTP responses by integrating with FakerPHP to generate realistic test data.

README 文档

README

This package helps you create mock HTTP responses for Laravel tests. It combines Laravel's Http::fake functionality with Faker data generation to create realistic test data in a format similar to Laravel factories.

Contents

1. Installation

composer require gromatics/http-fixtures --dev

That's all you need to install the package as a development dependency in your Laravel project.

2. What is a HTTP fixture and why do I need it?

An HTTP fixture is a class that mocks the data of a JSON API endpoint. Sometimes you don't want to hit a real API in your tests. APIs can go down, and while your code may work perfectly, a downed API can cause your tests to fail. A common way to solve this is to save the JSON response and serve it using Http::fake, like this:

$json = file_get_contents(dirname(__FILE__) . '/../../Fixtures/response.json');
Http::fake(["https://example.com/api" => Http::response($json, 200)]);

A saved JSON response can contain sensitive data, and it can be cumbersome to filter all of it out before committing the JSON to your repository. The Laravel HTTP Fixture package handles this for you. It can automatically create a fixture from an HTTP request and uses the Faker library to replace sensitive values, similar to how Laravel factories work. A HTTP fixture looks like this:

namespace Tests\Fixtures;

use Gromatics\HttpFixtures\HttpFixture;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class ExampleHttpFixture extends HttpFixture
{
    public function definition(): array
    {
        return [
            'status' => Arr::random(['OK', 'NOK']),
            'message' => $this->faker->sentence,
            'items' => [
                [
                    'identifier' => Str::random(20),
                    'name' => $this->faker->company,
                    'address' => $this->faker->address,
                    'postcode' => $this->faker->postcode,
                    'city' => $this->faker->city,
                    'country' => $this->faker->country,
                    'phone' => $this->faker->phoneNumber,
                    'email' => $this->faker->email,
                ]
            ],
        ];
    }
}

3. Creating a Fixture

3.1 Create a fixture from a real JSON response

The easiest way to create a fixture is by recording a real HTTP request in your test. You can do this by placing the Http::record() method before calling the service that makes the HTTP requests. After the service has finished, use HttpResponseRecorder::recordedToHttpFixture() to save the responses as fixtures.

A service can make multiple requests, and for each unique request, a new fixture will be created. If the same request is made more than once, it won’t duplicate the fixture.

For example:

use Gromatics\Httpfixtures\Services\HttpResponseRecorder;
use Illuminate\Support\Facades\Http;

it('creates a HTTP Fixture from a real JSON request', function () {
    Http::record(); 
    Http::get('https://api.stackexchange.com/2.2/search?order=desc&sort=activity&intitle=perl&site=stackoverflow&limit=1');
    HttpResponseRecorder::recordedToHttpFixture();
});
You can optionally provide a custom fixture name by passing it to the recordedToHttpFixture() method:
HttpResponseRecorder::recordedToHttpFixture('CustomFixtureName');

This will create a StackexchangeSearchFixture.php file in /tests/Fixtures, which might look like this:

class StackexchangeSearchFixture extends HttpFixture
{

    public function definition(): array
    {
        return [
          'items' => [
            0 => [
              'tags' => [
                0 => $this->faker->word(),
                1 => $this->faker->word(),
                2 => $this->faker->word(),
              ],
              'owner' => [
                'reputation' => $this->faker->numberBetween(10, 99),
                'user_id' => $this->faker->numberBetween(1000000, 9999999),
                'user_type' => $this->faker->word(),
                'profile_image' => $this->faker->word(),
                'display_name' => $this->faker->name(),
                'link' => $this->faker->url(),
              ],
              'is_answered' => $this->faker->boolean(),
              'view_count' => $this->faker->numberBetween(100, 999),
              'answer_count' => $this->faker->numberBetween(1, 9),
              'score' => $this->faker->numberBetween(0, 0),
              'last_activity_date' => $this->faker->unixTime(),
              'creation_date' => $this->faker->unixTime(),
              'last_edit_date' => $this->faker->unixTime(),
              'question_id' => $this->faker->numberBetween(10000000, 99999999),
              'content_license' => $this->faker->sentence(3),
              'link' => $this->faker->url(),
              'title' => $this->faker->words(3, true),
            ],
            ...

3.2 Create a fixture using the Artisan command

You can also create a fixture using an Artisan command. Just run the command below and follow the on-screen instructions:

php artisan make:http-fixture

3.3 Create a fixture from a JSON file

You can also create a fixture from a saved JSON file. For example, if you’ve saved a Stripe API response in your storage directory, you can do the following:

php artisan make:http-fixture

What is the class name of the HTTP Fixture? (e.g., StripeFixture, GoogleFixture): 
> StripeFixture

Want to paste a JSON response and turn it into a fixture? (yes/no) [no]: 
> y

What's the path of your JSON file? (e.g. storage/app/stripe-fixture.json:
> storage/app/stripe-fixture.json

If your Stripe response looks like this;

{
    "id": "pi_3NLxg2L1ZLzhUeQv0EXAMPLE",
    "object": "payment_intent",
    "amount": 2000,
    "amount_capturable": 0,
    "amount_received": 2000,
    "currency": "usd",
    "customer": "cus_Nv1EXAMPLE1",
    "description": "T-shirt order",
    "status": "succeeded",
    "payment_method": "pm_1NLxhHL1ZLzhUeQv1EXAMPLE",
    "receipt_email": "jenny.rosen@example.com",
    "created": 1712700000,
    "charges": {
        "object": "list",
        "data": [
            {
                "id": "ch_3NLxg2L1ZLzhUeQv0lEXAMPLE",
                "object": "charge",
                "amount": 2000,
                "currency": "usd",
                "status": "succeeded",
                "payment_method_details": {
                    "card": {
                        "brand": "visa",
                        "last4": "4242",
                        "exp_month": 12,
                        "exp_year": 2026
                    },
                    "type": "card"
                },
                "receipt_url": "https://pay.stripe.com/receipts/acct_1EXAMPLE/rcpt_EXAMPLE"
            }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "/v1/charges?payment_intent=pi_3NLxg2L1ZLzhUeQv0EXAMPLE"
    }
}

Then the command will generate a fixture class similar to this:

namespace Tests\Fixtures;

use Gromatics\HttpFixtures\HttpFixture;
use Illuminate\Support\Str;

class StripeFixture extends HttpFixture
{
    public function definition(): array
    {
        return [
            'id' => Str::random(20),
            'object' => $this->faker->word(),
            'amount' => $this->faker->numberBetween(1000, 9999),
            'amount_capturable' => $this->faker->numberBetween(0, 0),
            'amount_received' => $this->faker->numberBetween(1000, 9999),
            'currency' => $this->faker->currencyCode(),
            'customer' => $this->faker->word(),
            'description' => $this->faker->sentence(),
            'status' => 'succeeded',
            'payment_method' => $this->faker->word(),
            'receipt_email' => $this->faker->email(),
            'created' => $this->faker->numberBetween(1000000000, 9999999999),
            'charges' => [
                'object' => $this->faker->word(),
                'data' => [
                    0 => [
                        'id' => Str::random(20),
                        'object' => $this->faker->word(),
                        'amount' => $this->faker->numberBetween(1000, 9999),
                        'currency' => $this->faker->currencyCode(),
                        'status' => 'succeeded',
                        'payment_method_details' => [
                            'card' => [
                                'brand' => $this->faker->word(),
                                'last4' => $this->faker->numberBetween(10, 10000),
                                'exp_month' => $this->faker->numberBetween(10, 99),
                                'exp_year' => $this->faker->year(),
                            ],
                            'type' => $this->faker->word(),
                        ],
                        'receipt_url' => $this->faker->url(),
                    ],
                ],
                'has_more' => $this->faker->boolean(),
                'total_count' => $this->faker->numberBetween(1, 9),
                'url' => $this->faker->url(),
            ],
        ];
    }
}

4. Use a HTTP fixture in tests

You can use your HTTP fixture in your tests like this:

Http::fake(["https://api.stripe.com/v1/*" => Http::response(
    (new StripeFixture())->toJson(),  200),
]);

You can override specific keys when initializing the fixture:

Http::fake(["https://api.stripe.com/v1/*" => Http::response(
    (new StripeFixture(['description' => 'My first Stripe payment']))->toJson(),  200),
]);

This will return a JSON response similar to:

{
    "id": "CuOmvFTXUcSDMqRhm7ZI",
    "object": "voluptas",
    "amount": 7026,
    "amount_capturable": 2396,
    "amount_received": 8877,
    "currency": "SYP",
    "customer": "cum",
    "description": "My first Stripe payment",
    "status": "succeeded",
    "payment_method": "nihil",
    "receipt_email": "kirlin.brisa@yahoo.com"
}

You can also use dot notation to update nested values:

$fixture = (new ExampleHttpFixture(['items.0.name' => 'John Doe']))->toJson();

This will produce a response where the first item's name is set to "John Doe".

5. Fixture options

The output of the fixture can be in JSON, XML, array and a Laravel collection.

XML

If you want to return XML instead of JSON, you can use the toXML() method and pass the root element name as a parameter. For example:

Http::fake([
    "https://www.example.com/get-user/harry" => Http::response(
    (new ExampleHttpFixture())->toXml('yourRootElement'), 
    200),
]);

This will return na XML response similar to:

<?xml version="1.0"?>\n
<yourRootElement>
    <status>OK</status>
    <message>Voluptatum fugit aspernatur non.</message>
    <items>
        <item>
            <identifier>6zzzWFhmyRyPZwoYa6b8</identifier>
            <name>Schiller, Gislason and Reynolds</name>
            <address>5708 Lockman Gardens Armstronghaven, FL 32188</address>
            <postcode>87862-9490</postcode>
            <city>North Sabrina</city>
            <country>Romania</country>
            <phone>(346) 871-2661</phone>
            <email>marion66@yahoo.com</email>
        </item>
    </items>
</yourRootElement>

gromatics/http-fixtures 适用场景与选型建议

gromatics/http-fixtures 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3.2k 次下载、GitHub Stars 达 50, 最近一次更新时间为 2025 年 04 月 11 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 gromatics/http-fixtures 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 gromatics/http-fixtures 我们能提供哪些服务?
定制开发 / 二次开发

基于 gromatics/http-fixtures 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 3.2k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 50
  • 点击次数: 17
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 50
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-04-11