本文目的
最近使用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,如需轉載請自行聯系原作者