[英]Unit testing with mocks (PHP)
我有一個類:
class Foo {
function getCurrentBar() {
$model = Query::findByPk($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
}
所以基本上我的應用程序中一次只有一個條形,它作為整數存儲在會話中。 我經常調用一個輔助函數來查找模型實例,它會進行數據庫查詢。 還有緩存,但現在無關緊要。
我的問題是:我怎么單元測試這個 ? 我測試的類需要這個。 我想我可以改變會話以包含id但是這意味着我需要在數據庫中有相應的模型。
最好的方法是添加方法setCurrentBar()
僅用於單元測試嗎? 然后我可以模擬一個條形對象並設置它,它將用於所有單元測試。 那有意義嗎?
答案確實是依賴注入,但是你想要控制的依賴是條形的來源 ,而不是條形本身。
class Foo {
private $query;
function __construct($query)
{
$this->query = $query;
}
function getCurrentBar() {
$model = $this->query->findByPk($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
}
所以在您的生產代碼中
$query = new Query() // assuming findByPk() is made a normal non-static method
$realFoo = new Foo($query);
但是對於單元測試......
$testFoo = new Foo(new MockQuery());
其中MockQuery
是Query
類的模擬版本,它返回模擬條 。
您也可以選擇測試部分模擬對象,直到DI系統到位為止。
class Foo {
function getCurrentBar() {
$model = $this->getQueryResult($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
function getQueryResult($queryParams)
{
return Query::findByPk($queryParams);
}
}
然后做一個看起來有點像這樣的測試......
$myObjectToTest = $this->getMock('Foo', array('getQueryResult'), array(), '', true, true, true);
$myObjectToTest->expects($this->once())
->method('getQueryResult')
->with($whateverTheQueryParametersAre)
->will($this->returnValue($someResult));
$myObjectToTest->getCurrentBar();
您可以嘗試使用依賴注入 。
將Bar實例傳遞給Foo構造函數
class Foo
{
private _bar;
function __construct (Bar $bar)
{
$this->_bar = $bar;
}
public function getCurrentBar()
{
return $this->_bar;
}
}
然后,您可以在運行測試時注入模擬Bar對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.