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

Laravel控制器测试:如何Mock内部调用的服务方法

Laravel控制器测试中Mock服务层方法的实现指导

场景说明

你在Laravel项目中测试PageController的renderAboutUsPage方法时,需要MockPageService的getActivePageBySlug方法,避免触发真实的数据库查询,同时你已经单独完成了服务层方法的测试。

具体实现步骤

要Mock服务层方法,我们可以借助Laravel内置的Mockery工具,通过容器绑定替换真实的服务实例,具体操作如下:

1. 构建模拟的Page模型实例

首先创建一个模拟的Page模型对象,作为Mock服务方法的返回值:

$mockPage = Mockery::mock(Page::class);

2. Mock PageService的目标方法

创建PageService的模拟实例,指定getActivePageBySlug方法的调用规则:

$pageServiceMock = Mockery::mock(PageService::class);
$pageServiceMock->shouldReceive('getActivePageBySlug')
    ->once() // 验证方法被调用一次
    ->with('about-us') // 验证传入的slug参数正确
    ->andReturn($mockPage); // 指定方法返回模拟的Page实例

3. 将Mock实例绑定到Laravel容器

通过容器绑定,让控制器构造函数注入的是Mock服务而非真实实例:

$this->app->instance(PageService::class, $pageServiceMock);

4. 调整测试断言

由于Mock了服务层方法,服务层内部的日志(Getting page by active status and provided slug.)不会执行,需要删除对应的日志断言,否则测试会失败。

修改后的完整测试用例

/**
 * @test
 * @testdox 关于我们页面是否成功响应、渲染正确视图、包含view对象{data}并记录正确日志
 * @group website
 * @group static-pages
 */
public function test_whether_about_us_page_renders_successfully()
{
    // 创建模拟的Page模型实例
    $mockPage = Mockery::mock(Page::class);

    // Mock PageService并指定方法行为
    $pageServiceMock = Mockery::mock(PageService::class);
    $pageServiceMock->shouldReceive('getActivePageBySlug')
        ->once()
        ->with('about-us')
        ->andReturn($mockPage);

    // 绑定Mock实例到容器
    $this->app->instance(PageService::class, $pageServiceMock);

    // 断言控制器中的日志记录
    Log::shouldReceive('info')->once()->with("Rendering about-us static page.");

    // 发起请求
    $response = $this->get('about-us');

    // 响应与视图断言
    $response->assertStatus(200);
    $response->assertViewIs('pages.static-page'); 
    $response->assertViewHas('data', $mockPage); // 验证视图数据为模拟实例
}

扩展:异常场景测试

如果需要测试服务层抛出异常的情况(比如页面不存在),可以用andThrow()指定抛出的异常:

$pageServiceMock->shouldReceive('getActivePageBySlug')
    ->once()
    ->with('about-us')
    ->andThrow(new NotFoundHttpException());

// 断言响应状态为404
$response->assertStatus(404);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:25:18