所有分类
  • 所有分类
  • 后端开发
PHP 开发者必知:模拟和桩技术在单元测试中的神奇应用

PHP 开发者必知:模拟和桩技术在单元测试中的神奇应用

单元测试中,模拟和桩技术可用于:模拟:使用假对象替换依赖项,控制行为并验证交互。桩:创建专门的假接口,验证依赖项的调用情况。在单元测试中,模拟和桩技术对于孤立代码和验证其与依赖项之间的交互非常重要。模拟是一种替换实际依赖项的假对象,它允许您

做程序猿,搞单元测试是很有必要滴~因为它能保证我们写出的代码棒棒哒!我是个PHP开发者,对模拟(Mock)和桩(Stub)技术可是情有独钟!这俩玩意儿帮我把代码区分开来,确定每个模块都各干各事;而且还能检验我的代码是否真的需要依赖外部环境。今儿就给大家讲讲我用这个技术的小窍门。

模拟技术的理解和应用

说起模拟技术,我就觉得像变魔术似的。有了它们,我能制造出各种假的东西,这些假货能完美替换掉代码里的真家伙。比如说,我想试试一个管用户权限的功能,但这功能还得靠外面的数据库帮忙。所以,利用模拟技术,我搞出个数据库的假服务,它能随意改动返回的数据,这样我就能放心地测试权限部分了,不怕数据库出错或结果无常。

我常用PHP中的PHPUnit框架的`$this->getMockBuilder()`和`->getMock()`这两招来搞定模拟对象。这个方法挺直接的,通过设定模拟对象的方法和返回值,就能精准掌握测试环境,保证了测试结果的精度和可靠性!

桩技术的实践和价值

PHP 开发者必知:模拟和桩技术在单元测试中的神奇应用

跟@模似技术差不多,@桩技术对我来说也很实用!利用它我能为那些依赖的东西造出一些特定的接口,然后看看它们是不是都按规矩被调用了~比如,要测个网络请求处理函数的话,我就造个HTTP客户端的桩对象出来。看了它的调用情况后,我就能确信这个网络请求处理函数在该用的时候有没有用到HTTP客户端咯~

在用PHPUnit做测试时,我会用`->see()`这个方法做桩断言。这东西简单明了,看着就知道是干什么的,可以方便地检验桩对象的行为,保证我写的代码在真实环境下也能应付自如。

模拟与桩的结合应用

实际项目里,我发现模拟和桩很搭,用它们测东西准没错儿!比如,检测电商网购的订单处理过程时,要试试看数据库服务(保证订单数据靠谱)和支付服务桩(确认付款成功)能不能配合默契。这样就能更全面地测各种情况了,程序肯定稳如泰山!

实战案例:calculateTotal()函数的测试

// 在 $object 中模拟 MyService 类
$mock = $this->getMockBuilder(MyService::class)
    ->disableOriginalConstructor()
    ->getMock();
// 设置 mock 方法的预期行为
$mock->expects($this->once())
    ->method('doSomething')
    ->with('arg1', 'arg2')
    ->willReturn('result');
// 与模拟对象交互并进行断言
$this->assertSame('result', $object->doSomething('arg1', 'arg2'));

说到我最近做的项目,有个困扰就是怎么才能测好那个依靠外头服务的`CalculateTotal()`功能?你知道,这个函数就是用来算咱们购物车上所有东东的总价的,需要借助`ProductService`才行。然后为了能测试顺畅,我就想了个法子,用模拟来替代真实的`ProductService`。

首先,我用代码把`ProductService`变成了我家的小猫咪模型。接着,我给小猫装上了特别设计的`getPrice()`技能,这样它就能根据商品ID告诉我们预设好的价格。这样一来,即使没有真正的`ProductService`,我也能随心所欲地调整测试环境!

接下来,我弄了个测试案例,让`calculateTotal()`函数算下总价,给它传了几个商品ID进去。然后看看模拟对象上的`getPrice()`方法被调用的情况,就能知道`calculateTotal()`有没有找对`ProductService`,是不是算对了总价。

这个实战还是帮我确认了’calculateTotal()’函数没啥问题,更重要是让我明白了模似技术在单元测试里有多牛。用好模拟和桩技术,能大大提升测试效率和质量,还能在开发过程中早点发现并解决问题,保证软件稳定可靠。

总结与思考

// 为 $service 创建二重桩
$stub = $this->createMock(MyService::class);
// 设置实际依赖项,以便稍后断言
$object = new MyObject($stub);
// 与实际对象交互
$object->doSomething();
// 验证桩是否被调用
$this->assertTrue($stub->expects($this->once())
    ->method('doSomething')
    ->with('arg1', 'arg2')
    ->hasBeenCalled());

通过这段时间实操,我发现模拟和桩技术真的很重要!它们让我写出更好的代码,还能提高开发效率。不过,用得不好就容易搞复杂、误导开发。所以,咱们用的时候还是小心点儿。

所以,我觉得每个PHP用户得深入研究下这些技术,然后巧妙地运用到实际项目里去。用的时候也别忘了多想、多总结,尽量把它们的优点用到极致,避免可能出现的问题。

嘿亲们,我有个小问题问问大家哈~你们用模拟和桩技术时有没有遇到啥难题?又是怎么解决的呢?记得留言告诉我哦~咱们来好好聊聊这个话题,共同提升!

// 使用模拟来验证 calculateTotal()
$productServiceMock = $this->getMockBuilder(ProductService::class)
    ->disableOriginalConstructor()
    ->getMock();
$productServiceMock->expects($this->once())
    ->method('getProducts')
    ->willReturn([
        ['id' => 1, 'price' => 10],
        ['id' => 2, 'price' => 20]
    ]);
$total = calculateTotal($productServiceMock);
$this->assertEquals(30, $total);

原文链接:https://www.icz.com/technicalinformation/web/2024/06/17045.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?