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

Laravel功能测试中能否Mock未注入类的方法?

如何在Laravel功能测试中Mock直接实例化的类方法?

完全可以实现,针对你这种无法修改遗留代码、类是直接实例化的场景,Laravel结合Mockery可以轻松Mock指定方法,下面是具体实现方案:

核心思路

利用Laravel的服务容器绑定机制,将TaxService类的实例替换为预先Mock好的对象,这样当控制器中执行new TaxService()时,实际会使用Mock实例。

具体测试代码示例

假设你的控制器代码如下:

class SomeController extends Controller
{
    public function calculate()
    {
        $taxService = new TaxService();
        $cut = $taxService->calculateGovermentsCut(1000);
        
        return response()->json(['cut' => $cut]);
    }
}

对应的功能测试代码可以这么写:

use Tests\TestCase;
use App\Services\TaxService;
use Mockery;

class TaxCalculationTest extends TestCase
{
    public function test_calculate_goverments_cut()
    {
        // 1. 创建TaxService的Mock实例,指定目标方法的返回值
        $mockTaxService = Mockery::mock(TaxService::class);
        $mockTaxService->shouldReceive('calculateGovermentsCut')
            ->with(1000)
            ->andReturn(200);

        // 2. 将Mock实例绑定到服务容器
        $this->app->instance(TaxService::class, $mockTaxService);

        // 3. 调用接口并断言结果
        $response = $this->getJson('/api/calculate-tax');

        $response->assertStatus(200)
            ->assertJson(['cut' => 200]);
    }

    // 测试结束后清理Mockery实例
    protected function tearDown(): void
    {
        parent::tearDown();
        Mockery::close();
    }
}

关键说明

  • 当控制器中执行new TaxService()时,Laravel的服务容器会自动返回绑定的Mock实例,而非创建新的实例(这是Laravel的自动解析特性)。
  • 若需Mock该类的多个方法,可在shouldReceive后链式添加,或单独指定每个方法的行为。
  • 必须在测试结束后调用Mockery::close()清理Mock实例,避免影响其他测试用例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:54:54