Laravel如何使用Mockery伪造对象进行单元测试
发布时间 - 2025-11-15 00:00:00 点击率:次使用Mockery可在Laravel中模拟依赖对象,如PaymentGateway,通过伪造、设定期望行为、注入和断言来测试OrderService逻辑,避免真实调用外部服务。利用shouldReceive、with、andReturn等方法定义模拟行为,并通过$this->instance()将模拟对象绑定到容器,实现对控制器的测试,确保代码单元独立且可预测。
在Laravel中使用Mockery进行单元测试,主要是为了隔离外部依赖,比如数据库、队列、第三方API等,从而专注于测试当前类的行为。Mockery是一个强大的PHP模拟框架,与PHPUnit集成良好,Laravel也原生支持它。
安装与启用Mockery
Laravel项目通常已经内置了Mockery,如果你使用的是Laravel自带的测试工具集(如Pest或PHPUnit),无需额外安装。若需手动安装,可通过Composer:
composer require --dev mockery/mockeryLaravel的测试基类 TestCase 已经集成了Mockery,每次测试结束后会自动清理模拟对象。
基本用法:伪造一个服务类
假设你有一个订单服务 OrderService,它依赖于一个支付网关 PaymentGateway。你想测试下单逻辑而不真正调用支付接口。
定义服务类示例:
class PaymentGateway
{
public function charge($amount)
{
// 实际调用第三方API
}
}
class OrderService
{
protected $gateway;
public function __construct(PaymentGateway $gateway)
{
$this->gateway = $gateway;
}
public function createOrder($amount)
{
$result = $this->gateway->charge($amount);
return $result ? ['status' => 'success'] : ['status' => 'failed'];
}
}
编写测试,使用Mockery伪造PaymentGateway:
use Mockery;
use Tests\TestCase;
class OrderServiceTest extends TestCase
{
public function tearDown(): void
{
Mockery::close(); // Laravel通常自动处理
}
public function test_it_can_create_order_when_payment_succeeds()
{
// 创建模拟对象
$mockGateway = Mockery::mock('App\Services\PaymentGateway');
// 定义期望行为
$mockGateway->shouldReceive('charge')
->with(100)
->andReturn(true);
// 注入模拟对象
$service = new OrderService($mockGateway);
// 执行测试
$result = $service->createOrder(100);
// 断言结果
$this->assertEquals('success', $result['status']);
}
}
在Laravel容器中绑定模拟对象
如果服务是通过Laravel服务容器自动注入的(例如在控制器中),可以使用 $this->instance() 方法将模拟对象绑定到容器:
public function test_controller_action_with_mocked_service()
{
$mockGateway = Mockery::mock('App\Services\PaymentGateway');
$mockGateway->shouldReceive('charge')->with(50)->andReturn(true);
// 将模拟对象注入容器
$this->instance('App\Services\PaymentGateway', $mockGateway);
// 调用路由或控制器
$response = $this->post('/orders', ['amount' => 50]);
$response->assertStatus(200);
$response->assertJson(['status' => 'success']);
}
或者使用 app()->instance() 实现相同效果。
常用Mockery方法
- shouldReceive('method'):声明某个方法将被调用
- with($arg):断言传入参数
- andReturn($value):指定返回值
- andReturnNull():返回null
- andReturnUsing(Closure):动态返回值
- times(n):断言调用次数
- once()、twice():简化调用次数断言
- andReturnSelf():链式调用支持
例如:
$mock = Mockery::mock('SomeClass'); $mock->shouldReceive('process') ->with('data') ->andReturnUsing(function ($arg) { return strtoupper($arg); });
基本上就这些。只要理解“伪造对象 → 设定期望 → 注入使用 → 断言行为”的流程,就能高效地为复杂依赖写测试。Laravel + Mockery组合让单元测试更轻量可控。
# php
# laravel
# js
# json
# composer
# app
# 工具
# ai
# 路由
# gate
# NULL
# require
# 接口
# 对象
# this
# 数据库
# 绑定
# 链式
# 第三方
# 返回值
# 的是
# 是一个
# 单元测试
# 如果你
# 就能
# 你想
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在宝塔面板中修改默认建站目录?
Laravel如何实现本地化和多语言支持?(i18n教程)
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
Python高阶函数应用_函数作为参数说明【指导】
如何在Windows虚拟主机上快速搭建网站?
免费网站制作appp,免费制作app哪个平台好?
千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】
网易LOFTER官网链接 老福特网页版登录地址
香港网站服务器数量如何影响SEO优化效果?
HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
如何确保FTP站点访问权限与数据传输安全?
如何快速使用云服务器搭建个人网站?
如何在云指建站中生成FTP站点?
如何快速搭建安全的FTP站点?
详解Oracle修改字段类型方法总结
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
javascript中对象的定义、使用以及对象和原型链操作小结
EditPlus 正则表达式 实战(3)
JavaScript实现Fly Bird小游戏
laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法
如何在 React 中条件性地遍历数组并渲染元素
Laravel如何实现用户密码重置功能?(完整流程代码)
焦点电影公司作品,电影焦点结局是什么?
如何在IIS中新建站点并配置端口与物理路径?
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
php json中文编码为null的解决办法
如何为不同团队 ID 动态生成多个非值班状态按钮
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
Windows Hello人脸识别突然无法使用
js代码实现下拉菜单【推荐】
EditPlus中的正则表达式实战(5)
如何在建站之星网店版论坛获取技术支持?
太平洋网站制作公司,网络用语太平洋是什么意思?
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
教你用AI将一段旋律扩展成一首完整的曲子
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
如何用花生壳三步快速搭建专属网站?
Python结构化数据采集_字段抽取解析【教程】
如何利用DOS批处理实现定时关机操作详解
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Laravel如何使用Eloquent进行子查询
手机网站制作与建设方案,手机网站如何建设?


ock('SomeClass');
$mock->shouldReceive('process')
->with('data')
->andReturnUsing(function ($arg) {
return strtoupper($arg);
});