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

Laravel Pest/Mockery:如何不使用--parallel实现单独进程测试?

解决Pest中Mock硬依赖类的进程隔离问题

方案一:直接使用PHPUnit的进程隔离注解

Pest基于PHPUnit开发,无需依赖--parallel选项,直接给测试用例添加PHPUnit的进程隔离注解即可解决类加载冲突:

<?php

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */
test('测试Livewire组件getData方法', function () {
    // 创建重载Mock
    $connectorMock = Mockery::mock('overload:' . \App\Services\Connector::class);
    // 设定Mock方法的预期行为
    $connectorMock->shouldReceive('目标方法名')
        ->once()
        ->andReturn('模拟返回值');

    // 执行Livewire测试逻辑
    Livewire::test(\App\Http\Livewire\Example::class)
        ->call('getData', collect([]))
        // 替换为你的断言逻辑
        ->assertSuccessful();
});

注解说明:

  • @runInSeparateProcess:让当前测试在独立进程中运行,避免真实类已加载导致的Mock重载失败
  • @preserveGlobalState disabled:关闭全局状态保留,确保进程间环境完全独立

方案二:用容器解析替代硬实例化(更优解)

你提到担心依赖注入拖慢页面加载,但wire:init是页面加载后异步触发的方法,并非组件挂载时同步执行。可以修改组件代码,用Laravel容器获取Connector实例,无需进程隔离就能轻松Mock:

调整Livewire组件代码

public function getData(Collection $collection)
{
    // 用容器解析替代new Connector()
    $connector = app(\App\Services\Connector::class);

    // 原有业务逻辑
}

对应的Pest测试代码

test('测试Livewire组件getData方法', function () {
    // 创建普通Mock实例
    $connectorMock = Mockery::mock(\App\Services\Connector::class);
    $connectorMock->shouldReceive('目标方法名')
        ->once()
        ->andReturn('模拟返回值');

    // 将Mock绑定到容器,覆盖真实类
    app()->instance(\App\Services\Connector::class, $connectorMock);

    // 执行Livewire测试
    Livewire::test(\App\Http\Livewire\Example::class)
        ->call('getData', collect([]))
        // 替换为你的断言逻辑
        ->assertSuccessful();
});

这种方式测试效率更高,且完全不会影响页面加载速度——Connector只会在getData被异步调用时才会被容器实例化,组件初始化阶段不会触发任何耗时操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:37:35