我正在構建一個會話管理類和相關的單元測試。爲了將類與$ _SESSION的全局狀態分開,我使用了一個非常簡單的類來管理類和會話數據之間的綁定。PHPUnit模擬,每次返回相同的數組
Binding類的整個源如下:
class Binding implements iface\Binding
{
public function &getNamespace ($namespace)
{
return $_SESSION [$namespace];
}
}
在消耗Session類我有以下:
protected function initStorage()
{
// Check that storage hasn't already been bound to the session
if ($this -> storage === NULL)
{
// Attempt to start the session if it hasn't already been started
if (($this -> sessionId() !== '')
|| ((!$this -> headersSent())
&& ($this -> startSession())))
{
// Bind the storage to the session
$this -> storage =& $this -> binding -> getNamespace ($this -> namespace);
// Make sure the session is in a usable state
if (!$this -> hasData())
{
$this -> reset();
}
}
else
{
// We couldn't start the session
throw new \RuntimeException (__METHOD__ . ': Unable to initiate session storage at this time');
}
}
return $this;
}
的sessionId,headersSent和startSession是簡單的一行功能作爲「測試接縫」,我可以很容易地用PHPUnit中的模擬代替它。
我意識到在編寫測試時,我可以使用模擬綁定類做更多的事情,而不僅僅是從類中分離會話,我還可以將它用作觀察類的非公共屬性的一種方式,而無需實際上暴露了任何內部狀態,從而使這個階級變得脆弱。由於該類對數組的引用進行操作,而不是直接對數組進行操作,因此我可以觀察被引用的數組。
我一直希望用PHPUnit的模擬API來做到這一點,但我不知道該怎麼做。
我知道我可以創建一個返回一個這樣的數組進行模擬:
$mock = $this -> getMock ('iface\Binding');
$mock -> expects ($this -> any())
-> method ('getNamespace')
-> will ($this -> returnValue (array()));
這不是因爲雖然觀察狀態的改變是有用的,因爲它返回每一次不同的陣列。我需要的是每次都返回一個對同一個數組的引用的模擬。
最後,我寫了一個類採取實際Binding類的地方,並使用來代替:
class BindingMock implements iface\Binding
{
protected $storage = array();
public function &getNamespace ($namespace)
{
return $this -> storage [$namespace];
}
}
使用這個類讓我前和調用的東西后,檢查$存儲的內容會話API,因爲我可以查看存儲陣列中的內容,而不必在Session類中公開非公共狀態。下面是一個使用該技術的試驗例:
public function testCreateItem()
{
$storage =& $this -> binding -> getNamespace ('unittest');
$this -> assertEmpty ($storage);
$this -> object -> createItem ('This is a test', 'test');
$this -> assertNotEmpty ($storage);
$this -> assertEquals ('This is a test', $storage ['test']);
}
我寧願能夠生成使用PHPUnit的,但替代類,具有附加類只是單元測試似乎是錯誤的方式做到這一點,除非在PHPUnit中無法實現同樣的功能。
偏題...不錯的頭像! – Jrod 2012-08-09 22:18:15