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
相关产品推荐
相关产品推荐

