程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 如何在phpunit中模擬(mock)一個單例類

如何在phpunit中模擬(mock)一個單例類

編輯:關於PHP編程

一 Mock簡介
當我們對A類進行單元測試時,A類可能依賴了B類,為了減少依賴,方便A類方法的測試,我們可以模擬一個B類,簡單規定其各方法的返回值(而非真正實現具體邏輯)。
Phpunit中提供了一套模擬類的api,簡單使用如下:

class StubTest extends PHPUnit_Framework_TestCase
{
public function testStub()
{
// Create a stub for the SomeClass class.
$stub = $this->getMock(‘SomeClass’);
// Configure the stub.
$stub->expects($this->any())
->method(‘doSomething’)
->will($this->returnValue(‘foo’));
// Calling $stub->doSomething() will now return ‘foo’.
$this->assertEquals(‘foo’, $stub->doSomething());
}
}

在這個例子中,我們得到了一個’SomeClass’的模擬,規定其可以被調用任意次,如果調用doSomething方法,將得到值foo。


二 問題
我們知道,對於一個單例類,其constructor方法為private,而getMock的實現,默認是要調用原類的constructor方法。
如果SomeClass為單例,phpunit將會提示
Call to private SomeClass::__construct() from context ‘PHPUnit_Framework_TestCase’

這時,我們的測試該如何進行呢?


三 解決
仍然使用getMock進行模擬。
只要將其第5個參數設為false即可。其含意是:不調用原對象的構造函數。
$stub = $this->getMock(‘SomeClass’, array(), array(), ”, false);

不得不說,這樣使用有點復雜。

如果你使用的是phpunit3.5及以上版本, 那麼有更易用的api。你可以這樣禁掉對原有constructor方法的調用:

$stub=$this->getMockBuilder(‘SomeClass’)->disableOriginalConstructor()->getMock();

附:
對getMock的6個可選參數的詳解,參見:http://www.phpunit.de/manual/3.6/en/test-doubles.html

手冊中並未提及它們的默認值,經測試得到結果如下,貼出來方便大家使用。
array(), array(), ”, false, false, false

$stub=$this->getMockBuilder(‘SomeClass’)
等同於:
$stub=$this->getMockBuilder(‘SomeClass’,array(), array(), ”, true, false, false)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved