PHPUnit学习05Mock使用进阶

本文目的

最近使用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结合使用。

参考文档

原文地址:https://www.cnblogs.com/bourneli/p/2676981.html