You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHPUnit/Laravel中模拟JSON文件测试依赖服务的函数

在PHPUnit中模拟指定JSON数据测试依赖函数的方法

我来给你捋捋怎么在PHPUnit里模拟指定格式的JSON,来测试依赖那个外部数据Service的函数——核心思路就是把获取JSON的Service给Mock掉,让它在测试时返回你预设的JSON数据,不用真去调用外部源。下面是几种实用的实现方式:

方法一:Mock Service返回解析后的数组(推荐)

如果你的业务逻辑是把JSON解析成数组再处理,直接让Mock对象返回解析好的数组更高效,省得重复解析步骤:

use PHPUnit\Framework\TestCase;
use App\Services\ExternalDataService;
use App\Handlers\YourDependentHandler;

class YourDependentHandlerTest extends TestCase
{
    public function testProcessDataWithMockedJson()
    {
        // 按照你需要的JSON结构构造数组
        $mockParsedData = [
            "data" => [
                [
                    "title" => "Development",
                    "children" => [
                        [
                            "title" => "Settings",
                            "channel_types" => [["title" => "Network"]]
                        ],
                        [
                            "title" => "Testing",
                            "channel_types" => [["title" => "Social"]]
                        ]
                    ],
                    "created_at" => 1523460000 // 补全你的完整时间戳
                ]
            ]
        ];

        // 创建Service的Mock对象
        $mockDataService = $this->createMock(ExternalDataService::class);
        // 指定调用getJsonData方法时返回我们构造好的数组
        $mockDataService->method('getJsonData')
                        ->willReturn($mockParsedData);

        // 把Mock对象注入到依赖它的处理类里
        $handler = new YourDependentHandler($mockDataService);
        // 执行要测试的函数
        $handler->processData();

        // 写断言验证结果,比如检查是否正确提取了频道名称
        $this->assertContains("Network", $handler->getExtractedChannelTitles());
    }
}

方法二:Mock返回原始JSON字符串

如果你的函数需要直接处理JSON字符串(比如自己负责解析逻辑),可以让Mock对象返回预先写好的JSON字符串:

public function testProcessRawJsonWithMockedString()
{
    // 构造符合格式的JSON字符串
    $mockRawJson = '{
        "data": [
            {
                "title": "Development",
                "children": [
                    {
                        "title": "Settings",
                        "channel_types": [{"title": "Network"}]
                    },
                    {
                        "title": "Testing",
                        "channel_types": [{"title": "Social"}]
                    }
                ],
                "created_at": 1523460000
            }
        ]
    }';

    $mockDataService = $this->createMock(ExternalDataService::class);
    $mockDataService->method('getJsonData')
                    ->willReturn($mockRawJson);

    $handler = new YourDependentHandler($mockDataService);
    $handler->processRawJson();

    // 验证处理结果,比如检查子项数量是否正确
    $this->assertEquals(2, count($handler->getAllChildItems()));
}

方法三:从本地JSON文件读取测试数据

如果JSON结构特别复杂,写在代码里太臃肿,可以把测试用的JSON存到本地fixture文件(比如tests/fixtures/mock_data.json),测试时直接读取:

public function testProcessDataWithFixtureFile()
{
    // 读取本地JSON文件并解析成数组
    $mockJsonContent = file_get_contents(__DIR__ . '/fixtures/mock_data.json');
    $mockParsedData = json_decode($mockJsonContent, true);

    $mockDataService = $this->createMock(ExternalDataService::class);
    $mockDataService->method('getJsonData')
                    ->willReturn($mockParsedData);

    $handler = new YourDependentHandler($mockDataService);
    $handler->processData();

    // 断言顶级标题是否正确
    $this->assertEquals("Development", $handler->getTopLevelTitle());
}

几个关键注意点

  • 一定要保证Mock的方法名和实际Service中的方法名完全一致,大小写也不能错!
  • 如果你的Service是通过依赖注入传入的,测试时务必注入Mock对象,绝对不能用真实的Service实例(不然就变成集成测试了)
  • 复杂JSON用本地fixture文件更方便维护,修改测试数据不用动测试代码

内容的提问来源于stack exchange,提问作者Jenski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:47:02