PHPUnit学习05---Mock使用进阶

本文目的

最近使用php开发项目,并用phpunit进行单元测试,使用phpunit的mock机制有一段时间了,决定记录使用经验,方便以后查阅。

 

mock例子

public function testBit(){
	$oClientMock = $this->getMock('SomeClient'); // 创建mock对象

	$oClientMock->expects($this->once()) // 设定次数

	   	    ->method('ExecuteCommand') // 设定方法

	  	    ->with(CPU_BIT_CMD) // 设定方法入参

		    ->will($this->returnValue('some')); // 设定方法返回值

	$oHardware = new MHardware($oClientMock);

	$this->assertEquals('32', $oHardware->CpuBit()); // 调用方法并断言

}
 

简而言之,使用mock一般有下面几步:

  1. getMock 创建mock对象(必须有)
  2. method 设置期望调用的方法(必须有)
  3. expects 设置方法调用的次数(必须有)
  4. with 设置调用方法时的入参(可选)
  5. will 设置调用方法后的返回值(可选)

 

getMock函数签名详解

getMock有7个参数,一般只需要使用第一个参数指定被mock的类即可,但是如果需要更灵活的配置mock,有必要了解其他参数:

  1. String – Required – 需要mock的类的名称
  2. Array – Optional – 需要mock的函数名称数组,默认情况下,会mock所有函数(即给所有函数一个空的实现),但是如果设置了需要mock的函数,那么其他函数将不会被mock,按照原来的方式执行。
  3. Array – Optional – 需要传入给构造函数的参数,getMock方法帮你调用了构造函数,所以这里通过一个数组,给你设置构造函数参数的机会
  4. String – Optional – 给这个mock类起一个名称,这样可以使用这个新名称创建许多同样的mock类实例。
  5. Boolean – Optional – true将调用原始对象的构造函数,false将不掉用,默认为true
  6. Boolean – Optional – true将可以调用原始类的clone函数,false则无法调用。
  7. Boolean – Optional – false将禁止__autoload函数被调用,当mock对象被创建时。

 

匹配器(Matchers)

匹配器相当于调用mock方法的量词,作为expects函数的参数传给mock对象,用于设定期望的调用次数,主要有下面几个:

once() 期望方法只调用一次,否则测试失败

never() 期望方法从不被调用,否则测试失败

any() 期望调用任意次,测试永远不会因此失败。

at($index) 期望方法被第$indexd调用的行为,$index从0开始,一般会配合with或will使用。值得注意的是$index是针对特定mock对象而言的,而不是针对特定mock对象的特定方法。也就是说,mock对象A任意一个方法被调用一次,$index会增加1。

exactly($times) 期望执行准确的次数,否则测试失败

atLeastOnce() 期望执行至少一次,否则测试失败

约束(Constraints)

约束和with一起使用,用于设定mock函数的输入,约束有很多,主要分为一下几大类

[数组]

arrayHasKey(mixed $key) 断言入参数组是否有指定的键

contains(mixed $value) 断言入参数组是否有指定的值

[逻辑]

logicalAnd($constraint,$constraint) 断言两个参数逻辑和

logicalNot($constraint) 断言参数逻辑否

logicalOr($constraint,$constraint) 断言两个参数逻辑或

logicalXor($constraint,$constraint) 断言两个逻辑异或

[字符串]

matchesRegularExpression($pattern) 断言入参是否匹配正则表达式

stringContains($string, $case) 断言入参是否包含表达式

stringEndsWith( $suffix) 断言入参是否有此后缀

stringStartsWith(string $prefix) 断言入参是否有次前缀

[比较]

identicalTo($value) 断言入参===当前值

equalTo($value, $delta = 0, $maxDepth = 10) 断言入菜是否==当前值

lessThan($value) 断言入参<当前值

lessThanOrEqual(mixed $value) 断言入参<=当前值

greaterThan(mixed $value) 断言入参>当前值

greaterThanOrEqual(mixed $value) 断言入参>=当前值

[类和对象]

attribute($constraint, $attributeName) 将约束赋给指定属性或对象

attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10) 断言value是否与当前对象的某个属性相等

classHasAttribute($attributeName) 断言当前类是否具有摸个属性

classHasStaticAttribute($attributeName) 断言当前类是否具有某个静态属性

hasAttribute($attributeName) 断言当前对象是否有指定的属性

[基本类型]

isFalse() 断言当前值为FALSE

isTrue() 断言当前对象是否为TRUE

isInstanceOf(string $className) 断言当对象是某个类的实例

isNull() 断言当前对象是否为NULL

isType($type) 断言当前对象是某个具体的类型

[其他]

anything() 接受任何入参

fileExists() 断言当前入参代表的文件是否存在

返回

设定返回值,与will一起使用,用于设定mock函数的返回值,主要方法方法如下:

returnValue($value) 返回字面意思

throwException($exception) 此方法在调用时抛出指定异常

returnArgument($index) 返回第$index个参数,从0开始

returnCallback($fun) 返回值通过回调函数生成,函数签名与被mock的函数相同

onConsecutiveCalls(arg0,arg1,…) 设定返回值列表,这样可以控制被返回值的顺序,更灵活的控制返回值,最好与匹配器anyatLeastOnce结合使用。

 

参考文档

PHPUnit单元测试对桩件(stub)和仿件对象(Mock)的理解 一、桩件(stub)和仿件对象(Mock)概念 桩件(stub): 将对象替换为(可选地)返回配置好的返回值的测试替身的实践方法称为上桩(stubbing)。可以用桩件(stub)来“替换掉被测系统所依赖的实际组件,这样测试就有了对被测系统的间接输入的控制点。这使得测试能强制安排被测系统的执行路径,否则被测系统可能无法执行”。 仿件对象(Mock): 将对象替换为能验证预期行为(例 阅读详情

相关推荐

YOLO26涨点改进 | 小目标损失函数独家改进篇 | TGRS 2025 | 引入AdaFocalLoss损失函数,改进小目标检测,自适应聚焦小目标与样本分布不平衡,提升检测精度与训练稳定性

本文提出将AdaFocalLoss损失函数应用于YOLO26模型优化,有效提升小目标检测性能。AdaFocalLoss通过目标尺寸感知机制和IoU引导的动态调节,自动调整训练权重和聚焦程度,解决了样本不平衡问题。相比传统损失函数,它无需手动调参,能增强训练稳定性,在多尺度、复杂场景下表现优异。文章详细介绍了AdaFocalLoss的原理、优势及实现方法,并提供了代码集成指南。实验表明该方法能显著提升检测精度和鲁棒性,特别适用于小目标检测任务。

Ai缝合怪、助力小伙伴高效发论文 264

AI辅助编程实战:提示工程与上下文管理指南

AI辅助编程不是用英语写代码的魔法,而是人机协同的新范式——其核心在于理解大语言模型(LLM)的本质:基于概率采样的文本生成器,而非具备推理能力的智能体。要释放真实生产力,必须掌握三大支柱:精准的提示工程(Prompt Engineering)、动态的上下文管理(Context Management)和以人为中心的决策闭环。这决定了AI输出是‘可验证的协作者’还是‘不可控的黑箱’。技术价值体现在将调试效率提升3倍、文档准确率从42%升至91%、SQL优化成本下降99.8%等可度量结果。典型应用场景覆盖IDE

weixin_33811539的博客 381

【SpringBoot】1、创建第一个SpringBoot项目

创建SpringBoot项目可以通过两种方式,1、通过访问:https://start.spring.io/,SpringBoot的官方网站进行创建SpringBoot项目;2、通过工具(例如:Idea)创建SpringBoot项目。本次使用开发工具:Idea创建我的第一个SpringBoot项目。 首先,打开我们的Idea开发工具 选择Create New Poject(创建一个新的项目) ...

JACKAL 21万+

PHPPHPUnit单元测试利器:PHP Mock使用方法

由于环境依赖关系,或者是特殊环境的构造要求,这就可能导致我们在测试环境下做验证是很困难的。 当我们无法直接使用的真实被依赖模块时,我们可以用“测试替身”(Test Double)来代替。这个测试替身不需要与真实的被依赖模块有相同的行为,它只需要提供和真实的被依赖模块有相同的API就行了。 PHPUnit提供的getMock($className)方法可以自动生成一个对象,而这个对象就可以作为原来那...

qq_26249609的博客 1889

Anthropic Claude 3.5 Sonnet技术解析与企业级API部署实践

大语言模型(LLM)作为当前AI工程落地的核心载体,其能力演进遵循从基础推理到工具协同、再到安全可控的渐进路径。Claude系列模型依托宪法式对齐(Constitutional AI)原理,在长上下文理解、代码生成与多步骤推理方面持续突破,技术价值体现在高保真响应、低幻觉率与可审计行为链。典型应用场景覆盖智能客服知识中枢、合规文档自动审查、研发辅助编程等企业级闭环任务。本文聚焦2024年6月发布的Claude 3.5 Sonnet,结合真实API权限管控、Tool Calling集成及计算机使用(Compu

weixin_34007020的博客 538

PHP开发900个实用技巧】194.PHPUnit测试替身: Mock对象让你轻松测试复杂依赖!

本文深入讲解了PHPUnitMock对象的使用,旨在帮助开发者解决单元测试中的复杂依赖问题。文章首先介绍了Mock对象的概念,将其比作“演员替身”,用于在测试中替代真实依赖,从而避免外部因素对测试的干扰。接着,文章阐述了Mock对象的必要性,指出当代码依赖数据库、第三方API等不可控因素时,Mock可以提供稳定、可控的测试环境。文章还详细介绍了Mock实战的五步法,包括创建Mock对象、设置方法返回值、注入被测对象、执行测试方法和验证交互行为。此外,文章还提供了高级避坑指南,包括如何处理静态方法、fina

1103

phpunit 无法mock静态方法的解决方案

参考:http://miljar.github.io/blog/2014/01/29/phpunit-testing-static-calls/ 采用Di设计,将静态方法包裹以后,mock掉封装的容器即可。 或者采用mockery. 但是大量使用静态方法,其实是设计上的偷懒,说严重点写代码水平不够。好好看看框架源码,这才是设计王道。 ...

chp_woAIdan的博客 495

ATVOSS分层设计深度剖析:Device、Block、Kernel、Tile与Basic层的协同工作原理

ATVOSS(Ascend C Templates for Vector Operator Subroutines)是一套基于Ascend C开发的Vector算子库,致力于为昇腾硬件上的Vector类融合算子提供极简、高效、高性能、高拓展的编程方式。其核心优势在于通过模块化分层设计,实现各级模板的复用、替换与定制,让开发者能够快速构建针对昇腾硬件优化的算子。 ## 揭秘ATVOSS五层架构:从

gitblog_00051的博客 677

Deep-SVDD-PyTorch预训练策略:Autoencoder初始化提升模型精度

Deep-SVDD-PyTorch是一个基于PyTorch实现的深度支持向量数据描述(Deep SVDD)异常检测方法。该项目通过Autoencoder预训练策略为模型参数提供智能初始化,显著提升异常检测精度,是初学者和研究人员探索深度异常检测的理想工具。 ## 为什么选择Autoencoder预训练? 在异常检测任务中,模型初始化对最终性能有重要影响。Deep-SVDD-PyTorch创新性

gitblog_00001的博客 420

PHPUnit学习03---使用Mock对象解决测试依赖

本文目的 单元测试过程中经常会遇到被测试函数A依赖另一个函数B,但是B已经完全测试过,没有必要在测试A的时候重复测试B。如何去除这种不必要的测试呢?本文探讨了如何手动解决测试依赖,更进一步地,结合PHPUnitMock API,提出更加优雅,高效的解决方案。 一个例子 假设有一个订单管理类OrderManager,它的私有变量中,有一个OrderDao,当插入订单时,首先OrderMana...

weixin_33767813的博客 194

php插桩,PHP | PHPUnit单元测试利器:PHP Mock使用方法

由于环境依赖关系,或者是特殊环境的构造要求,这就可能导致我们在测试环境下做验证是很困难的。当我们无法直接使用的真实被依赖模块时,我们可以用 “测试替身”(TestDouble)来代替。这个测试替身不需要与真实的被依赖模块有相同的行为,它只需要提供和真实的被依赖模块有相同的API就行了。PHPUnit提供的getMock($className)方法可以自动生成一个对象,而这个对象就可以作为原来那个...

weixin_35125159的博客 518

phpunit骚操作之静态类的部分mock

通过官方文档以及实践得知,含有静态方法的类如果需要mock,就要使用前缀 alias: ,但是随之而来有个问题是后面无法调用这个类本身的方法,所以通过阅读源码可以使用以下方法来实现:1.创建 Helpers 类进行封装 2.创建静态类 3.测试运行............

fangdong88的博客 686

如何在phpunitmock一个单例类

Mock简介当我们对A类进行单元测试时,A类可能依赖了B类,为了减少依赖,方便A类方法的测试,我们可以模拟一个B类,简单规定其各方法的返回值(而非真正实现具体逻辑)。Phpunit中提供了一套模拟类的api,简单使用如下: class StubTest extends PHPUnit_Framework_TestCase { public function testStub() ...

网站开发初中级代码参考-转载 264

PHPUnit 单元测试简介

引入PHPUnit 安装

老鹰之歌的学习笔记 2750

PHPUnit学习笔记(四)断言详解

断言(Assertions)是PHPUnit提供的一系列对程序执行结果测试的方法。通俗的讲,就是断言执行程序结果为我们期待的值,如果不是则测试失败,下面是断言方法的详细介绍,内容全部来翻译自PHPUnit的官方文档,部分方法官方介绍的很模糊,我根据官方的源码注释增加了说明和注释 assertArrayHasKey(mixed $key, array $array[, str...

weixin_34304013的博客 321

TCN-BiLSTM多变量单步时序预测MATLAB完整代码和数据

TCN-BiLSTM多变量单步时序预测MATLAB完整代码和数据从 Excel 文件读取时间序列数据,并构建带时间滞后的数据集;搭建 TCN 与 BiLSTM 结合的混合神经网络;对数据进行归一化处理,划分训练集与测试集;使用 Adam 优化器训练模型;进行单步预测,计算预测误差(MAE、RMSE、MAPE);可视化预测结果。平台:MATLAB2024b

上一篇: Effective C++条款37:绝不重新定义继承而来的缺省参数值
下一篇: jQuery之事件绑定
weixin_34192993
博客等级 码龄11年 5343粉丝 175原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值