本文目的
最近使用php开发项目,并用phpunit进行单元测试,使用phpunit的mock机制有一段时间了,决定记录使用经验,方便以后查阅。
mock例子
简而言之,使用mock一般有下面几步:
<b>getMock</b> 创建mock对象(必须有)
<b>method</b> 设置期望调用的方法(必须有)
<b>expects</b> 设置方法调用的次数(必须有)
<b>with</b> 设置调用方法时的入参(可选)
<b>will</b> 设置调用方法后的返回值(可选)
getMock函数签名详解
getMock有7个参数,一般只需要使用第一个参数指定被mock的类即可,但是如果需要更灵活的配置mock,有必要了解其他参数:
String – Required – 需要mock的类的名称
Array – Optional – 需要mock的函数名称数组,默认情况下,会mock所有函数(即给所有函数一个空的实现),但是如果设置了需要mock的函数,那么其他函数将不会被mock,按照原来的方式执行。
Array – Optional – 需要传入给构造函数的参数,getMock方法帮你调用了构造函数,所以这里通过一个数组,给你设置构造函数参数的机会
String – Optional – 给这个mock类起一个名称,这样可以使用这个新名称创建许多同样的mock类实例。
Boolean – Optional – true将调用原始对象的构造函数,false将不掉用,默认为true
Boolean – Optional – true将可以调用原始类的clone函数,false则无法调用。
Boolean – Optional – false将禁止__autoload函数被调用,当mock对象被创建时。
匹配器(Matchers)
匹配器相当于调用mock方法的量词,作为expects函数的参数传给mock对象,用于设定期望的调用次数,主要有下面几个:
<b>once()</b> 期望方法只调用一次,否则测试失败
<b>never() </b>期望方法从不被调用,否则测试失败
<b>any()</b> 期望调用任意次,测试永远不会因此失败。
<b>at($index)</b> 期望方法被第$indexd调用的行为,$index从0开始,一般会配合with或will使用。值得注意的是$index是针对特定mock对象而言的,而不是针对特定mock对象的特定方法。也就是说,mock对象A任意一个方法被调用一次,$index会增加1。
<b>exactly($times) </b>期望执行准确的次数,否则测试失败
<b>atLeastOnce()</b> 期望执行至少一次,否则测试失败
约束(Constraints)
约束和with一起使用,用于设定mock函数的输入,约束有很多,主要分为一下几大类
<b>[</b><b>数组]</b>
<b>arrayHasKey(mixed $key)</b> 断言入参数组是否有指定的键
<b>contains(mixed $value)</b> 断言入参数组是否有指定的值
<b>[</b><b>逻辑]</b>
<b>logicalAnd($constraint,$constraint)</b> 断言两个参数逻辑和
<b>logicalNot($constraint)</b> 断言参数逻辑否
<b>logicalOr($constraint,$constraint)</b> 断言两个参数逻辑或
<b>logicalXor($constraint,$constraint)</b> 断言两个逻辑异或
<b>[</b><b>字符串]</b>
<b>matchesRegularExpression($pattern)</b> 断言入参是否匹配正则表达式
<b>stringContains($string, $case)</b> 断言入参是否包含表达式
<b>stringEndsWith( $suffix)</b> 断言入参是否有此后缀
<b>stringStartsWith(string $prefix)</b> 断言入参是否有次前缀
<b>[</b><b>比较]</b>
<b>identicalTo($value)</b> 断言入参===当前值
<b>equalTo($value, $delta = 0, $maxDepth = 10)</b> 断言入菜是否==当前值
<b>lessThan($value)</b> 断言入参<当前值
<b>lessThanOrEqual(mixed $value)</b> 断言入参<=当前值
<b>greaterThan(mixed $value)</b> 断言入参>当前值
<b>greaterThanOrEqual(mixed $value)</b> 断言入参>=当前值
<b>[</b><b>类和对象]</b>
<b>attribute($constraint, $attributeName)</b> 将约束赋给指定属性或对象
<b>attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10)</b> 断言value是否与当前对象的某个属性相等
<b>classHasAttribute($attributeName)</b> 断言当前类是否具有摸个属性
<b>classHasStaticAttribute($attributeName) </b>断言当前类是否具有某个静态属性
<b>hasAttribute($attributeName)</b> 断言当前对象是否有指定的属性
<b>[</b><b>基本类型]</b>
<b>isFalse()</b> 断言当前值为FALSE
<b>isTrue()</b> 断言当前对象是否为TRUE
<b>isInstanceOf(string $className)</b> 断言当对象是某个类的实例
<b>isNull()</b> 断言当前对象是否为NULL
<b>isType($type)</b> 断言当前对象是某个具体的类型
<b>[</b><b>其他]</b>
<b>anything() </b>接受任何入参
<b>fileExists() </b>断言当前入参代表的文件是否存在
返回
设定返回值,与will一起使用,用于设定mock函数的返回值,主要方法方法如下:
<b>returnValue($value)</b> 返回字面意思
<b>throwException($exception)</b> 此方法在调用时抛出指定异常
<b>returnArgument($index)</b> 返回第$index个参数,从0开始
<b>returnCallback($fun)</b> 返回值通过回调函数生成,函数签名与被mock的函数相同
<b>onConsecutiveCalls(arg0,arg1,…)</b> 设定返回值列表,这样可以控制被返回值的顺序,更灵活的控制返回值,最好与匹配器<b>any</b>或<b>atLeastOnce</b>结合使用。
参考文档
<a href="http://www.phpunit.de/manual/3.4/en/api.html#api.assert.assertThat.tables.constraints">PHPUnit Constraints</a>
<a href="http://www.phpunit.de/manual/3.4/en/test-doubles.html#test-doubles.mock-objects.tables.matchers">PHPUnit Matchers</a>
<a href="http://mark-story.com/posts/view/Default.aspx?__tencentip=10.16.108.34&__tencentid=1&__tencentrawurl=http://mark-story.com/posts/view/getting-familiar-with-phpunit-mocks">Getting familiar with PHPUnit Mocks</a>
<a href="http://stackoverflow.com/questions/4702132/modifying-objects-in-returncallback-of-phpunit-mocks">Modifying objects in returnCallback() of PHPUnit Mocks</a>
本文转自bourneli博客园博客,原文链接:http://www.cnblogs.com/bourneli/archive/2012/09/08/2676981.html,如需转载请自行联系原作者