2011年1月18日 星期二

facebook是如何管理代碼的

原文在此 ,看完之後,終於明白為什麼優秀的工程師都去了/想去facebook,因為那裡是工程師們的天堂。

譯文:

我對facebook的運轉著迷。 這是一個很獨特的環境,不容易被複製(他們的體係並不適合所有的公司,即使他們努力嘗試過)。 下面是我和facebook的朋友們關於他們如何開發和管理項目的記錄。

現在距離我收集的這些信息又過去6個月了,我相信facebook肯定又對他們的項目開發實踐進行了改進。 所以這些記錄可能會有點過時。 同時facebook的工程師驅動文化也越來越為大眾所知。 非常感謝那些幫助我整理這篇文章的facebook的朋友們。

記錄:

截止到2010年6月,facebook有將近2000名員工,10個月前只有1100名,一年之間差不多翻了一番。
兩個最大的部門是工程師和運維,每個部門大概都是400-500人。 這兩個部門人數大約佔了公司的一半。
產品經理與工程師的比例大約為1-7到1-10。
每個工程師入職時,都要接收4-6週的培訓,通過修補bugs和聽高級開發工程師的課程來熟悉facebook。
培訓結束後,每個工程師都可以接觸線上的數據庫(更大的權力意味著更大的責任,也有一份"勿做清單",不然可能會被開,比如共享用戶的隱私數據)。
有非常牢靠的安全體系,以免有人不小心/故意做了些不好的事。
每個工程師可以修改facebook的任何代碼,隨時可以遷入。
濃厚的工程師驅動文化。 "產品經理基本可以被忽略",這是facebook一名員工的話。 工程師可以修改流程的細節,重新安排工作任務,隨時植入自己的想法。
在每月的跨部門會議上,由工程師來匯報工作進度,市場部和產品經理會出席會議,也可以做些簡短的發言,但如果說得太多,很可能就會被打小報告。 他們確實想讓工程師來主導產品的開發,對自己的產品負責。
項目需要的資源都是自願的
一個產品經理把工程師們召集到一起,讓他們對他的想法產生興趣。
工程師們決定開發那些讓他們感興趣的特性。
工程師跟他們的經理說:"我下週想開發這5個新特性"。
經理會讓工程師獨立開發,可能有時會讓他優先完成一些特性。
工程師獨立完成所有的特性——前端/後端/數據庫,等等所有相關的部分。 如果需要得到設計人員的幫助,需要先讓設計人員對你的想法產生興趣。 其他如架構之類的也一樣。 但總體來說,工程師要獨立完成所有的任務。
對於某個特性是否值得開發的爭論,通常是這麼解決的:花一個星期的時間完成他,並在小部分人群中(如1%)進行測試。
工程師常常希望解決難題,這能獲得聲望和尊敬。 他們很難對前端項目或UI設計產生太大的興趣。 這跟其他公司可能正好相反。 在facebook,後端任務,比如新的feed算法,廣告投放算法,memcache優化等等,是工程師真正感興趣的。
所有的代碼修改都要進行審核(通過一個或多個工程師),但News Feed是個例外,因為太重要了,Zuckerberg會親自review。
所有的修改至少要被一個人審核,而且這個系統可以讓任何人很方便地審核其他人的代碼,即使你沒有邀請他
工程師負責測試,代碼修復,和維護自己的項目。
每個辦公室或通過VPN連接的員工會使用下一版的facebook,這個版本的facebook會經常更新,通常比公開的早1-12小時。 所有的員工被強烈建議提交bugs,而且通常會很快被修復。
很奇怪只有很少的QA或自動測試——"大部分工程師都能寫出基本沒有bug的代碼,只是在其他公司他們不需要這麼做。如果有QA部門,他們只要把代碼寫完,扔給他們就行了"
[針對上一條]我們有自動測試,代碼發布前必須要通過測試。 我們不相信"所有的工程師都能寫出沒有bug的代碼",畢竟這是一個商業公司。
很奇怪,缺少產品經理的影響和控制——產品經理是很獨立的和自由的。 產生影響力的關鍵是與工程師和工程師的領導們們搞好關係。 需要大致了解技術,不要提一些愚蠢的想法。
所有提交的代碼每週二打包一次。
只要多一分努力,終於一天會發生改變。
星期二的代碼發布,需要所有的提交過代碼的工程師在場。
代碼打包前,工程師必須在一個特殊的IRC channel上。
運維執行打包過程
facebook有大約60000台服務器
有9個代碼發布級別
最小的級別只有6台服務器
星期二的代碼發布會先發佈到6台服務器上,運維組會檢測這6台服務器的反應,保證代碼正常工作,然後再提交到下一級
如果發佈出現了一些問題(如報錯等等),那麼就停止下一級的部署,提交出錯代碼的工程師負責修復問題,然後從頭繼續發布。
所以一次發布可能會經歷幾次重複:1-2-3-fix. 回到1. 1-2-3-4-5-fix. 回到1. 1-2-3-4-5-6- 7-8-9
運維組是受過嚴格訓練,倍受尊敬,而且有商業意識的。 他們的工作包括分析錯誤日誌,負載和內存狀態等等。 還包括用戶行為。
代碼發布期間,運維組使用IRC-based頁面系統,可以通過facebook/email/irc/im/sms ping每一個工程師,如果需要他們注意的話。 對運維組不做回應是一件很羞愧的事。
代碼一旦發佈到第9級,並且穩定運行,就算發布成功了。
如果一個特性沒有按時完成,也沒什麼大不了的,下次完成時一併發布即可。
如果被svn-blamed,public shamed或工作經常疏忽就很可能被開除。 "這是一個高效的文化"。 不夠高效或者不夠聰明的員工會被剔除。 管理層會在6個月的時間裡觀察你表現,如果不合格,只能說再見。 每一級都是這個待遇,即使是C級別和VP級別,如果不夠高效,也會被開除。
被責罵不會導致解僱。 我們特別尊重別人,原諒別人。 大部分高級工程師都或多或少犯過一些嚴重的錯誤,包括我。 但沒有人因此被解僱。
我也沒有遇到過因為上面提到過的犯錯誤而被解僱。 有些人犯了錯,他們會非常努力地去修復,也讓其他人得到了學習。

--EOF--
若無特別說明,本站文章均為原創,轉載請保留鏈接,謝謝

reference : http://blog.leezhong.com/translate/2011/01/18/how-facebook-ships-code.html

2011年1月17日 星期一

如何在 PHP 中平順地處理 Error 及 Exception ?

在開發 PHP 的時候,最麻煩的事情之一就是處理錯誤。一個好的程式除了要將錯誤訊息呈現給使用者知道之外,也要讓該結束的部份正常結束才行。

而在 PHP5 之後,除了以往的 Error Handling 之外,還多了 Exception Handling ,使得程式變得更難去處理錯誤;所以大多數的開發者只能雙手一攤,讓這些錯誤訊息大剌剌地出現在使用者面前。

有沒有什麼好方法可以讓我們好好控制 Error 和 Exception 呢?


傳統的做法
在很多書籍和網路範例裡,當程式出錯時就是讓程序直接死掉,最常見的就是資料庫連線:

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
或是在送出導向 header 後,就直接 exit :

header("Location: http://www.example.com/"); /* Redirect browser */

/* Make sure that code below does not get executed when we redirect. */
exit;
這些都不是好做法,因為有些流量較大的網站裡可能有多個資料庫連線,或是檔案的 handler 仍在開啟中;如果直接讓程序死亡或離開的話,就沒辦法將這些已經開啟的資源給正常關閉掉,進而造成系統的不穩定。

Exception 的處理
PHP5 中,有個 set_exception_handler 這個函式,它可以幫我們處理 Exception :

function exception_handler($exception)
{
echo "Uncaught exception: " , $exception->getMessage(), "\n";
}

set_exception_handler('exception_handler');

throw new Exception('Uncaught Exception');
echo "Not Executed\n";
不過我個人認為用 try…catch 會讓我們在程式流程上的彈性更大:

function inverse($x)
{
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}

try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}

// Continue execution
echo 'Hello World';
而在我研究過 Zend Framework 的做法後,發現它在處理 Exception 上更加聰明。 Zend Framework 在 Controller 中引入一個 Response 物件,所有對瀏覽器的輸出都要經過它 (例如 Header 、 Content Body 等等) ;而這個 Reponse 物件也同時控管著 Exception 是否要被輸出到瀏覽器端,讓程式開發者能有更大的空間處理 Exception 。

以下我簡單把 Zend Framework 在 Response 物件中處理 Exception 的概念整理成一個自製的 Response 類別:

class Response
{
private $_exceptions = array();

private $_renderExceptions = false;

public function setException(Exception $e)
{
$this->_exceptions[] = $e;
}

public function getExceptions()
{
return $this->_exceptions;
}

public function isException()
{
return !empty($this->_exceptions);
}

public function renderExceptions($flag = null)
{
if (null !== $flag) {
$this->_renderExceptions = $flag ? true : false;
}

return $this->_renderExceptions;
}

public function sendResponse()
{
echo "Header sending...\n";
$exception = '';
if ($this->isException() && $this->renderExceptions()) {
foreach ($this->getExceptions() as $e) {
$exception .= $e->getMessage() . "\n";
}
echo $exception;
}
echo "Body sending...\n";
}
}
主要的概念很簡單,就是 Response 物件先把 Exception 先收集起來,然後再視狀況如何處理,例如:

$response = new Response();
$response->renderExceptions(true); // 讓 Exception 呈現出來
try {
// 這裡處理我們真正要執行的動作
throw new Exception('TEST'); // 丟出一個測試用的例外
} catch (Exception $e) {
$response->setException($e); // 收集例外
}

if ($response->isException()) {
// 可以在這裡記錄 Exception
}
$response->sendResponse(); // 顯示所有結果 (包含 Header, Exception, Body 等)
透過了 Response 物件來管理 Exception ,就可以不必因為 Exception 而中斷我們的程式碼。

PHP Error 的處理
雖然 Exception 可以用 try…catch 控制程式流程,但 PHP Error 卻不行。

因為一般處理 PHP Error 的方法是透過 set_error_handler,而當執行完自訂的 Error Handler 後,我們卻只能選擇繼續執行下一行程式碼或將程式中斷離開,不然就是要利用全域變數來設定錯誤旗標以達到控制的目的。

$error = false;

function exceptionErrorHandler($errno, $errstr, $errfile, $errline)
{
global $error;
$error = true;

echo $errstr, "\n";
return true;
}

set_error_handler("exceptionErrorHandler");

strpos();

if (!$error) {
echo "Do normal process here.\n";
}

echo "end.\n";
不過 PHP5 也幫我們想好了,我們可以在 Error Handler 裡丟出 ErrorException ,就可以配合前面提到的 Response 物件做到更平順的 Exception 處理:

function exceptionErrorHandler($errno, $errstr, $errfile, $errline )
{
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("exceptionErrorHandler");

$response = new Response();
$response->renderExceptions(true); // 讓 Exception 呈現出來
try {
// 這裡處理我們真正要執行的動作
trigger_error('TEST', E_USER_ERROR); // 改用 trigger_error 來丟出測試用錯誤
} catch (Exception $e) {
$response->setException($e); // 收集例外
}

if ($response->isException()) {
// 可以在這裡記錄 Exception
}
$response->sendResponse(); // 顯示所有結果 (包含 Header, Exception, Body 等)
這邊最棒的是 Error Handler 丟出 ErrorException 後, try…catch 就會發生作用,而不再像 set_error_handler 這樣又返回中斷的地方繼續執行,一切就像行雲流水般那麼自然。

結論
一個運作良好的系統必須要對錯誤的發生有最大的掌控權,而不是放任它讓系統墜毀在五里霧之中。

雖然前面提到的處理方式也許不是最佳的,但希望透過這樣的介紹,讓大家能夠思考自己的程式應該如何去處理錯誤這件事。

就寫到這裡吧,收工~

reference : http://www.jaceju.net/blog/archives/1121

Code commit policy ( using Git )

在上一篇,提到了我其實寫了不少 internal document (自己的一整套 Starter Guide, Code Convention, Commit Policy, Best Practice )。

我設計的 commit policy 其實是這樣的。

1. 所有站台 deploy 到 production 的 code 一率吃 master。

2. 大規模的改版會從 master 裡面 branch 出一個 staging 來持續開發。staging 開發完成沒問題之後才會 deploy。

3. 已經上線的 code 除了改 wording 之類的票,一率不准直接改 master。必須要另外弄一個 branch 出來做,這個 branch 強制吃票號,比如說 ticket 是 1234,則 branch 為 t1234。( 推上 remore)做完 peer review 沒問題之後才能 merge 回 master / staging,然後 deploy。

4. 稍微大一點的功能允許自訂 branch 名稱,比如說整個前台升 rails3,則可以開一個 rails3 branch。

5. 採取 meta commit 原則,可以是一個 method,一個 controller,一個 model 作一次 commit。確保 code review 能夠順利的進行。極度不鼓勵改 10 次檔案才 commit 一次,除非這是一張票,內容就是改這 10 個檔案的某個相同處。

6. 牽扯到 DB schema 變更的 commit / push 或太大規模的改寫,必須在公開頻道喊過務必確保同事知情。

7. * 絕對禁止 push 未完成(同事一拉下來結果爛光光)的 code,必須自己「手動」檢查過 code(如果有寫 test 就要 run test)才可 push。
* 絕對不能用假想的方式修完 code 就 commit push 甚至 deploy。
* 絕對禁止下班前一個小時 push + deploy。

8. (5) 與 (6) 累犯者(超過 3 次者) 踢出團隊,拒絕合作。

有幾點需要特別解釋為甚麼要這樣設計。

1. 曾經有試過 production 與 master 並行,然後從 master 裡 cherry pick 回去 production。後來發現的問題是懶 RD 修 bug 有時候會直接 commit 在 production,而且 cheery pick 回去本來就比較複雜,加上這種情況,事情就會變得很複雜。後來重新思考過,主幹跑 master 再加上 ticket branch 事情就會變得簡單很多。

2. staging 加上 ticket branch 也很好丟上 staging 環境測有沒有問題…

3. RD 寫 code 一率 peer review,除了可以早期發現 junior RD 寫 code 的問題,meta commit 也可以讓 RD 習慣 一次單純只處理一件事,處理太多事一心多用寫出來的 code 會很糟糕。

4. 全域的變更要通知大家「不是一種禮貌」,而是「不通知亂炸大家就叫不禮貌」

5. 嚴格禁止 commit 爛掉的 code 是因為一炸就是浪費 *所有人* 的時間。自己炸自己就算了,炸大家的人最不能夠原諒。

6. 接近下班時間寫出來的 code 品質最糟糕(肚子餓+想回家)。更麻煩的是閃了晚上如果真的爛了就找不到人。所以下班前一小時禁止 push / deploy。

7. 做錯事而且屢勸不聽的人不處理那就等於虐待沒做錯事的人。而且一天到晚炸 code 的人,其實就是一顆對 business 的不定時炸彈。沒事為甚麼有人想養炸彈在家裡…

reference : http://blog.xdite.net/?p=1974

2011年1月14日 星期五

Why is my time() off or behind by 8 hour in php?

solution :
date_default_timezone_set('Asia/Taipei');

inno n23 mobile手機品質很爛,再好用也沒用,不推薦買,要買請先三思

奉勸各位不要買,
為了滅少跟我一樣的受害者,
我把我的切身之痛寫給各位參考...

這一支手機是我生平第一次讓我如此氣憤的手機。
這支手機我買了NT4000,
手機買來後的第六天,營幕出現龜列,送回原廠維修,收了我NT800(幹)

南機場旁邊的那間遠傳門市人員說這一支他們賣了五十多支,還沒有收到過維修單,我想說就故且信你一次,
五十多支沒有任何維修單,品質應該就如同你當初跟我拍胸口保證的那樣,一極棒(幹,現在證實是你所說的都是謊言)

手機現在才用了1個月左右,充電的接孔出現接觸不良的情況,現在無法充電。

你們要買時,請勿必三思,不要相信門市人員的話,

我會把這一篇文章Po到各大部落格,以免還有人跟我一樣身受其害!

How to get the path of the PHP BIN from PHP?

You can use:
constant(not recommend)
PHP_BINDIR gives the directory where the php executable is found.

method(recommend)

public function getPHPExecutableFromPath(){
$paths = explode(PATH_SEPARATOR, getenv('PATH'));
foreach ($paths as $path) {
$php_executable = $path . DIRECTORY_SEPARATOR . "php" . ("WIN" === strtoupper(substr(PHP_OS, 0, 3)) ? ".exe" : "");
if (file_exists($php_executable) && is_file($php_executable)) {
return $php_executable;
}
}
return false; // not found
}

2011年1月6日 星期四

How to get server UTC timezone offset


$this_tz_str = date_default_timezone_get();
var_dump($this_tz_str);
$this_tz = new DateTimeZone($this_tz_str);
$now = new DateTime("now", $this_tz);
$offset = $this_tz->getOffset($now);
echo $offset/3600;

2011年1月5日 星期三

How to set ZendDebugger PHPUnit in Zend studio 8.0

Predefined:
Apperv2.5.10
PHP5.2
Zend Studio 8.0

(按bug icon in menu右邊的三角形icon) -> 「Debug Configurations」



「PHP Script」->「New launch configuration(左上角的icon)」



Name:「PHPUnitMyDebugger」
Execution environment:「php5」
PHP File:「/path/to/PHPUnit/phpunit.php」


Click Apply!

In Tab PHP Script Arguments
Script Arguments:「${resource_loc}」


In Tab Common(As below)


Click Apply! You have complete first part setting~~

Next part is setting you php.ini
Add below config to bottom of php.ini

[Zend]
zend_extension="C:\Program Files (x86)\Zend\Zend Studio - 8.0.0\plugins\org.zend.php.debug.debugger.win32.x86_5.3.18.v20100905\resources\php53\ZendDebugger.dll"
zend_debugger.allow_hosts=127.0.0.1
zend_debugger.expose_remotely=always
zend_debugger.connector_port = 10013

save php.ini and restart Apache.

我設成功時,是有連同PHPUnit也一起設定好。所以如果您做了以上的設定後,還是無法成功跟ZendDebugger時,
你也設一下PHPUnit吧



在Program上「New launch configuration」
Name:「PHPUnit」
Location:「/path/to/phpunit/phpunit_ori.bat」
Working Directory:「${workspace_loc}」
Arguments:「${workspace_loc}」


In common tab


click Apply. OK~ That is all my setting process~

2011年1月2日 星期日

PHPMock: Independent Mock Object/Stub Framework

Sometimes I think my readers must get terribly bored with my one track entries – I seem to roll through phases: a few weeks of OpenID, then a few of PHPSpec, then a detour for several months on X . That’s what you get for reading an open source developer’s weblog – we can only really work on one thing at a time so there’s a lack of variety.

Anyway, after that minor detour, this one’s a brief notice that we’ve commenced work (as of a while ago really) on PHPMock.

If you remember, I had one of those long winded blog posts about Mock Objects and Stubs in SimpleTest/PHPUnit and PHPT. Now that I’ve really launched into PHPSpec development, I’m finding a few spots here and there where my attention levels drop and I need a diversion. Which means PHPMock is seeing activity – there’s a whole branch written over a few days to get an API discussion going between developers.

The purpose of PHPMock is to write an independent Mock Object/Stub framework – something you can use in any scenario or xDD approach – from a PHPUnit Unit Test, to a PHPSpec Spec, to a PHPT test file. SimpleTest isn’t left out either – PHPMock is self contained so it should travel well.

Once we get over the Mock vs Stub approach question to such a framework (Are Mocks complicated Stubs, or Stubs simplified Mocks?) we’ll have a firm design and an API to develop with. I’m currently favouring an API in a simple readable form, e.g.

[geshi lang=php]// setup
$mockPerson = PHPMock::mock(‘Person’);
$mockPerson->shouldReceive(‘hasName’)->withNoArgs()->once()->andReturn(false);

// implemented use case
$mockPerson->hasName(); //FALSE

// verification of Mock expectations
$mockPerson->verify(); //TRUE[/geshi]

Not sure if it will stay that way, have some alternate API appended (less verbose), or end up as something different. I’ll let you know.

A good feeling about this small project is that we have peers checking in. Sebastian Bergmann for PHPUnit, me for PHPSpec, and Travis Swicegood for PHPT and maybe SimpleTest. So at least it’s not just me rumbling around enforcing my divine will .

If you want to look around the experiemental branch code, we’re hosted over at http://code.google.com/p/phpmock/.

reference : http://blog.astrumfutura.com/2007/11/phpmock-independent-mock-objectstub-framework/

The Mockery: PHP Mock Objects Made Simple

As I explored in my previous post, PHP Mock Objects: Sucking Ass Since Forever, Mock Objects in PHP have had difficulty gaining traction. One of the targets of this examination (in between variations of “I love PHPUnit”) was PHPUnit’s Mock Objects implementation. My main point, I suppose, was that with PHPUnit being the de-facto standard for unit testing, its mock objects implementation left a lot to be desired. As the later comments suggested, suger coating the situation won’t change the fact I’m criticising one of the most deeply embedded libraries in PHP practice (well, actually a teeny tiny bit of it).

So what is Mockery? Mockery is a mock object framework. You can use it to mock, stub and dazzle your classes into submission – even when they don’t exist yet . Mock objects are almost a given when it comes to Test-Driven Development, but even non-TDD unit testing can use mocks and stubs. They encourage test isolation, stand in for classes you haven’t implemented yet, and can replace resource intensive tasks with mocked versions (since we like our tests to run really fast). Using Mock Objects (or Stubs) is just incredibly useful.

So what does Mockery offer you, the unit tester?

1. It integrates with pretty much any conceivable testing framework with almost no effort.
2. It’s simple to use, intuitive, and specifically works with the language we use to describe object interactions.
3. The API is uncluttered and minimal.
4. Flexibility is its cornerstone allowing it to accurately and succintly express your requirements.
5. It enables simple one-off setups that can be later modified so you don’t need to re-specify entire mocks for every single test.
6. If you use Ruby and PHP, it will make your day (yes, I also write Ruby – sue me).

Why consider it instead of PHPUnit’s or (insert PHP testing framework)’s mock object implementation?

1. It ports to ANY testing framework with zero effort
2. It isn’t inspired by Java
3. It has no gotchas, requirements for custom callback code, or complicated and frustrating setups.
4. It’s capable of mocking real objects and performing mock object recordings of existing processes.
5. Expectations are not pre-constrained – you hold the rope.

Time for the inevitable API exploration… Mockery is written for PHP 5.3, so get your namespace booties on. If you cannot currently adopt PHP 5.3, read along anyway. You’ll be using PHP 5.3 eventually .

You can find Mockery on Github at http://github.com/padraic/mockery. Besides the code, there is one massive README that will go into the API and usage in far more detail than I can do in this article. It is currently not released to a PEAR channel, but I’ll be doing so once I feel happy that the framework has enough hard-core crazy features to last its lifetime in PHP. You can, however, clone from the git repository and install it via PEAR using the included package.xml file. I love issue reports – if you have them, don’t be stingy and keep them to yourself.

For those who find themselves curious about how, specifically, Mockery pits against PHPUnit Mock Objects, I’ll run a later article contrasting the two in terms of features and examples.

The basis of Mockery’s API is the English language. It’s a Domain Specific Language (DSL) in the form of a fluent interface. Given that basis, it’s not surprising that Mockery’s intent is to capture every possible object expectation within a DSL statement that reads like English.

For example, let’s assume we have the class Engineering which is utilised by the class Starship. Hey, I wrote a whole article based on a dodgy Klingon once so get with the programme. We’re testing the Starship class, and find that there is no Engineering class…yet. So we shrug, and decide to use a mocked object to replace Engineering. One of the consequences of this approach is that, down the line, the mock usage will actually specify the API our real Engineering class should use (this is test-driven DESIGN, afterall).

To boot up the creative juices, we start with a story:

Given our Starship has located a planet, it will instruct Engineering to turn off the warp drive, and then to divert 40% power to sensors, and then to divert 20% power to auxilliary engines, and finally to run a Level-1 diagnostic on itself. All instructions must be given once in this precise order. There may optionally be many diagnostic runs of any Level at any stage in the process. The Starship must report whether the operation was successful. Success is measured by successfully passing a Level 1 diagnostic.

Okay, so what exactly are we expecting?

[geshi lang=php]use \Mockery as M;

require_once ‘Starship.php’;

class StarshipTest extends PHPUnit_Framework_TestCase
{
public function testEngineeringResponseToEnteringOrbit()
{
$mock = M::mock(‘Engineering’);
$mock->shouldReceive(‘disengageWarp’)->once()->ordered();
$mock->shouldReceive(‘divertPower’)->with(0.40, ‘sensors’)->once()->ordered();
$mock->shouldReceive(‘divertPower’)->with(0.30, ‘auxengines’)->once()->ordered();
$mock->shouldReceive(‘runDiagnosticLevel’)->with(1)->once()->andReturn(true)->ordered();
$mock->shouldReceive(‘runDiagnosticLevel’)->with(M::type(‘int’))->zeroOrMoreTimes();

$starship = new Starship($mock);
$this->assertTrue($starship->enterOrbit());
}

public function teardown()
{
M::close();
}
}[/geshi]

There’s the test. Our mock has been setup according to the expectations implicit in the feature story. As you might notice, the final diagnostic calls are unordered (can occur at any time between ordered calls). For PHPUnit, the teardown() method is optional if you configure PHPUnit to use the bundled TestListener. I added it to show that it’s the sole integration needed with a testing framework (unless using the bundled TestListener for PHPUnit).

Now let’s write just enough code to pass this test in Starship.php:

[geshi lang=php]class Starship
{

protected $_engineering = null;

public function __construct($engineering)
{
$this->_engineering = $engineering;
}

public function enterOrbit()
{
$this->_engineering->disengageWarp();
$this->_engineering->runDiagnosticLevel(5); // unordered call!
$this->_engineering->divertPower(0.40, ‘sensors’);
$this->_engineering->divertPower(0.30, ‘auxengines’);
$criticalResult = $this->_engineering->runDiagnosticLevel(1);
return $criticalResult;
}

}[/geshi]

Hurrah! The test passes. We’ve just tested Starship without needing a real Engineering object (or even a class of that name!). You can find this example in the examples directory on Github for Mockery, along with the phpunit.xml configuration and Bootstrap.php file used.

If something did go wrong with our expectations, Mockery would throw an Exception to complain about it.

The Mockery API also handles return values (including a return queue for multiple method invocations with the same arguments), of course, along with a host of other features and expectation term methods. Refer to the README up on Github. Like I said before, it’s very complete and informative. We’ve barely touched on the basics of Mockery in this article, so get reading.

reference : http://blog.astrumfutura.com/2010/05/the-mockery-php-mock-objects-made-simple/

Mockery 0.6 Released – PHP Mock Object Framework

Mockery is a Mock Object framework for PHP, compatible with most unit testing frameworks including PHPUnit. Its purpose is to implement a lightweight grammer for the creation and testing of Mock Objects, Test Stubs, and Test Spies as an alternative to the built-in support offered by PHPUnit, etc.

Mockery is hosted on Github (http://github.com/padraic/mockery) where you can find an extensive README covering its API and uses. The Mockery 0.6 release may be installed from the SurviveTheDeepEnd.com PEAR channel at http://pear.survivethedeepend.com.

Mockery 0.6 features:

- Full Mock Object and Test Stub support
- Lightweight fluent API
- Flexible mocking and stubbing
- Object Interaction Recording
- Natural language syntax and expectation constructs
- Supports generic (untyped) mock objects for rapid prototyping
- Simple partial mocking of real objects
- Both local and global Mock Object call ordering
- Built-in return value queue for repeated method calls
- Support for default expectations
- Support for expectation replacement and stacking
- Fluent API/Law of Demeter mocking

If that sounds complex, it’s not! Mockery can be picked up and used with little study.

Why Mockery?
Mockery’s objective is to simplify Mock Objects in PHP while maintaining significant flexibility and a default level of intuitive behaviour. In Mockery, Mock Objects behave exactly as you write them with liberal interpretations otherwise applied. Mockery was born out of my own need to innovate the use of Mock Objects in PHP and draw away from the original import of aging Mocking approaches from Java. While Java (and almost every other programming language) has been steadily progressing its mock object libraries, and complementing them with new solutions, PHP has a relatively static approach depending on similarly static library components. That result has seen solutions using clunky APIs, poorly described syntax and behaviour, a lack of focus on the practice of using Mock Objects, user confusion, and raised barriers to new programmers trying to learn about Mock Objects. Mockery is one potential solution to these problems. Also, as a dedicated Test-Driven Design user, I really want something that clicks immediately and doesn’t have any gotchas.

Installation
Mockery may be installed from its PEAR channel using:

pear channel-discover pear.survivethedeepend.com
pear install deepend/Mockery

Mockery is written in PHP 5.3 (I know, but all you 5.2 users will get there eventually ). It is released under a New BSD license.

Example
The README offers a good look at some examples, and explains the API in a lot of detail. If you are trying to figure something out, the README undoubtedly has a section for it. Here’s an API example (assuming Mockery namespace used as MK). We’re capturing an interaction where we login into a bookmarking service, check for the existance of a “php” tagged bookmark, add three more bookmarks and then recheck if a “php” tag exists (twice for fun). We’re mocking the service since we don’t actually want to mess with a real account! Following the description closely…

[geshi lang=php]$service = \MK::mock(‘MyService’);
$service->shouldReceive(‘login’)->with(‘user’, ‘pass’)->once()->andReturn(true);
$service->shouldReceive(‘hasBookmarksTagged’)->with(‘php’)->once()->andReturn(false);
$service->shouldReceive(‘addBookmark’)->with(‘/^http:/’, \MK::type(‘string’))->times(3)->andReturn(true);
$service->shouldReceive(‘hasBookmarksTagged’)->with(‘php’)->twice()->andReturn(true);[/geshi]

The example uses some of the basic parts of Mockery to describe some interaction with a mocked web service class (obviously
also stubbing the web service’s responses in terms of booleans). The setup is straightforward, easy to follow, and there’s zero
misinterpretations possible. Our description was likewise simple and uncomplicated. The third line just shows two argument matchers at work, a default regex (intrepreted from any string argument set so long as any eventual string comparison fails and it’s a valid regex) and a Type matcher set to match any valid string.

To put this into some perspective, here’s an equivalent attempt using PHPUnit in a similar order of thought (excerpt from a test).

[geshi lang=php]$service = $this->getMock(‘MyService’);
$service->expects($this->once())->method(‘login’)->with(‘user’, ‘pass’)->will($this->returnValue(true));
$service->expects($this->once())->method(‘hasBookmarksTagged’)->with(‘php’)->will($this->returnValue(false));
$service->expects($this->exactly(3))->method(‘addBookmark’)
->with($this->matchesRegularExpression(‘/^http:/’), $this->isType(‘string’))
->will($this->returnValue(true));
$service->expects($this->exactly(2))->method(‘hasBookmarksTagged’)->with(‘php’)->will($this->returnValue(true));[/geshi]

Besides the differences in API, there are others. If MyService is just intended as a fake unimplemented object (the class doesn’t exist), Mockery carries on and just uses a generic Mock instance without error. PHPUnit will throw an exception, however, stating that login() is not a valid method. If we assume the class is real, but missing some methods, the same thing happens and PHPUnit complains about missing methods. Eventually, you’ll get the idea to implement the dependent class… If we add all the relevant methods (say, we mock an interface with all methods declared), PHPUnit STILL fails. This time complaining that hasBookmarksTagged() was expected only once. This occurs because PHPUnit has no capacity for stacking later expectations, and so, it ignores the second (and any later) ones. We can fix that by merging both into a single expectation using:

[geshi lang=php]$service = $this->getMock(‘MyService’);
$service->expects($this->once())->method(‘login’)->with(‘user’, ‘pass’)->will($this->returnValue(true));
$service->expects($this->exactly(3))->method(‘hasBookmarksTagged’)->with(‘php’)
->will($this->onConsecutiveCalls(false, true, true));
$service->expects($this->exactly(3))->method(‘addBookmark’)
->with($this->matchesRegularExpression(‘/^http:/’), $this->isType(‘string’))
->will($this->returnValue(true));[/geshi]

Using OnConsecutiveCalls() to create a return value queue, and merging the two stacked expectations, allows the PHPUnit variant to pass. Unlike Mockery, if there were ten hasBookmarksTagged() calls, you would need to add all ten return values (Mockery let’s you set the last return value to act infinitely). The merging simply demonstrates that complex class interactions across classes will fall victim to the need to constantly merge expectations until they are unreadable and explain little.

While your mileage may vary, Mockery just doesn’t need reworking, deep thought or extra work. Just state what you want your Mock Object to do in plain unconfused English according to your natural thought order! If nothing else, it helps make the expected interaction obvious which makes your tests more readable and explicit.

Feedback
Any issues can be reported via our Github hosted issue tracker. If you wish to discuss Mockery in more detail, you’re welcome to join the mailing list at http://groups.google.com/group/phpmockery.

reference : http://blog.astrumfutura.com/2010/05/mockery-0-6-released-php-mock-object-framework/

Mockery: From Mock Objects to Test Spies

With next week seeing the formal release of Mockery 0.6 which is currently fermenting on Github at http://github.com/padraic/mockery, I’m already looking forward to next piece of the puzzle arriving with 0.7. Mockery is an opportunity to being something new and fresh to the PHP mock objects environment beyond a far neater flexible API.

If you follow the test double debate in other languages there are two popular concepts making their presence felt. The first is that the over-specified definitions of test doubles (we have dummy objects, test stubs, mock objects, test spies and fake objects) do more harm than good since in reality we never really distinguish (nor care to) between most of them. In most cases we just sort of wing it, using our own concepts and intent to create test doubles which do what we want with little thought as to the kind of test double we’re creating. In the end, the definitions all merge together into a spectrum of possible behaviours we add as and if needed.

The second is that we’re seeing a lot more attention over whether Mock Objects are the best way to do things. Nobody doubts they have the right idea with Mock Objects, but the upfront setting of expectations may come across as unintuitive. A typical test begins with exercising code, and thereafter we typically make assertions on the behaviour (whether it be a resulting state change or an object interaction). Mock Objects reverse that – we expect first, and then we exercise the code.

With the future (before end of June) 0.7 release, Mockery will offer an alternative approach to the traditional Expect-Exercise-Verify cycle called the Test Spy. 0.6 already offers a measure of that capability through its ability to record interactions, though recording is completely automated and geared primarily towards comparing two sets of source code which should behave identically (e.g. during refactoring). The new Test Spy implementation will be API driven, using a similar form to Mockery’s existing Mock Object approach.

Why Test Spies?

Using Test Spies returns to the test based approach of exercising code first, and then making assertions. There’s a reason why this cyclical approach is used in unit testing. It’s easy to understand and makes sense from the start. Applying it to what we do with Mock Objects can make using Test Doubles in general easier to learn and teach. It may also remove barriers to entry for those who simply never understood Mock Objects or loathed their expectation setup. Test Spies also operate on a selective basis – where Mock Objects require upfront expectations to define how they will behave, Test Spies just do what you need them to and then allow selective assertions afterwards (i.e. you only need to test what you want to test).

The difference, once you see the code, is very subtle. Not unusually for testing practices, subtle differences in approach rely on the YMMV yardstick. Some people prefer the upfront expectation setting, others find the after-use assertion approach easier to understand or as more applicable to their thinking.

By supporting both approaches as equal citizens, Mockery once again lets go of the proverbial rope around your neck tied there by Java traditions. You’ll be free to go with whatever approach you find yourself preferring. Better, they can both co-exist in relative peace since they are drawn from the same framework and both share nearly all of the exact same API elements, with the exact same meaning. Whether you prefer Mock Objects or Test Spies (both equally are capable of being used as Test Stubs), they are both equally understandable by anyone using Mockery.

As a means of showing the differences, here are two test cases. The first is written using the Mock Object terminology, the second using the Test Spy terminology – each actually achieves the exact same goal.

[geshi lang=php]use \Mockery as M;

class StarshipTest extends PHPUnit_Framework_TestCase
{

public function testEngagingWarpDrive()
{
$engineering = M::mock(‘Engineering’);
$engineering->shouldReceive(‘prepForWarpFactor’)->with(8)->once()->andReturn(true);
$engineering->shouldReceive(‘engage’)->once();

$starship = new Starship($engineering);
$starship->accelerateToWarp(8);
}

}[/geshi]

Or, using a Test Spy approach.

[geshi lang=php]use \Mockery as M;

class StarshipTest extends PHPUnit_Framework_TestCase
{

public function testEngagingWarpDrive()
{
$engineering = M::mock(‘Engineering’);
$engineering->whenReceives(‘prepForWarpFactor’)->thenReturn(true);

$starship = new Starship($engineering);
$starship->accelerateToWarp(8);

$engineering->assertReceived(‘prepForWarpFactor’)->with(8)->once();
$engineering->assertReceived(‘engage’)->once();
}

}[/geshi]

To demonstrate the selective assertion approach, what if we just didn’t care about whether or not the engage() method was used? In that case, we could just drop it from the assertions altogether – never mentioning it in the test at all. In the Mock Object approach, we cannot do this – mocking means we must set all methods expected (otherwise the methods would not exist on the mock). We could even drop the assertion on prepForWarpFactor, although we still need to retain the stubbing of its return value (since it’s needed).

Supporting Test Spies and Mock Objects also has the other obvious benefit that you can switch modes effortlessly. There will always be cases where expectation setting is preferable over assertions and vice versa. Both have their uses even if you heavily prefer any one over the other.

Watch for the Mockery 0.6 release next week! I’ll follow through with Test Spies in 0.7 once I get the final API down (working on making it even shorter than our Mock Object API can achieve).

reference : http://blog.astrumfutura.com/2010/05/mockery-from-mock-objects-to-test-spies/

The Mockery: An Independent Mock Object and Stub Framework for PHP5

Every testing framework supports Stubs and Mock Objects, well…most of them. No wait, only one really does! SimpleTest. Yes, PHPUnit has a whole chapter on the topic – but let’s just say it’s implementation is more than a little broken.

The side effect of SimpleTest hogging the only true working Mock Object implementation has been an overwhelming de-emphasis in using Mock Objects in PHP. In a world where Unit Testing has given way to Test-Driven Design (TDD), and TDD shows signs of slowly being replaced by, or at a minimum learning from, Behaviour Driven Development (BDD), this lack of Mock Objects just won’t do. PHP needs something concrete in the area.

To that end, and right on the back of my previous MutateMe release, I put my considerable and legendary talents (which exist somewhere between my overweening ego, and my dictionary of GTA IV phone numbers) to work to create Mockery. Unfortunately my conscience forces me to acknowledge the invaluable input from Travis Swicegood (who recently released one of my favourite books on git!) who was deeply involved in the discussions and prototype code around Mockery’s predecessor, PHPMock, and therefore deserves a lot of blam…er…credit .

You can download the initial PEAR package release of 0.1.0alpha from http://dev.phpspec.org/Mockery-0.1.0alpha.tgz or pull from git using the clone URL on the Github.com page at http://github.com/padraic/mockery.

Update #1: Support queries and/or comments and suggestions are also welcome to the Mockery mailing list at http://groups.google.com/group/mockery.

What Is Mockery?
Mockery is an independent Mock Object and Stub framework. It’s not tailored specifically to any one testing framework, rather it’s an entirely separate framework with a discrete API. The idea is that you can use this framework within PHPUnit, or SimpleTest, or anything else really, without being forced to rely on the built-in support (if any) that test framework provides.

Mockery was designed specifically to implement a form of Domain Specific Language (DSL). It makes extensive use of a fluent interface mixed with methods to approximate plain English. A mock object expectation could look like:

[geshi lang=php]$mock->shouldReceive(‘create’)->atLeast()->once()->atMost()->twice()->withAnyArgs()->andReturn(new stdClass);[/geshi]

There’s a lot packed into this single statement, and the natural flow of the DSL (there are no nested methods – only a linear fluent interface) is a major component in allowing your unit tests to remain readable. The API grammer itself is actually tiny – it’s how you mix and match them that makes things interesting and useful.

Being an independent framework, support for Mockery is non-existent in testing frameworks, but that’s not even necessary! Mockery will throw an exception of type Mockery_ExpectationException whenever the Mock Object is used in an unexpected fashion. Most testing frameworks natively report uncaught exceptions as Errors and print the exception’s message to the screen – so the only step needed is to ensure all Mocks are validated at the end of a unit test. Naturally, that would be a nice step to automate within testing frameworks but that’s not essential (maybe someone will hear my cry in the wilderness and adopt us though ).

What are these Mock Objects and Stubs?
Both Mock Objects and Stubs are variants of a Test Double. A Test Double is basically a fake object used to replace another real object in the test. Consider a simple scenario where a Model has a dependency on a Data Mapper, which in turn has a dependency on a database. You have two broad options:

1. Use a real database which means you are really testing the Model, the Data Mapper, and the DBMS as part of an integration test. This creates problems – databases are slow, need to be managed and reset, and why should the Data Mapper or even the database schema even exist yet?

2. Replace the Data Mapper with a fake – a Stub or Mock Object which implements an identical interface, but returns canned predictable responses with a negligible performance hit.

Many people will identify with the first option – there are enough arguments over whether to use a real database when testing to realise it’s a common approach. Fewer will identify with the second, since it has normally (outside of SimpleTest) involved creating special subclasses or mini-stubs.

The purpose of Mockery is not to pass judgement on any practice however – that’s my personal domain . Mockery supports both Mock Objects and Stubs as equal citizens.

The difference between Mocks and Stubs is easier to grasp. A Stub is a static object – it’s created to return canned responses to all method calls. There’s nothing more complicated to learn – it’s that simple.

A Mock Object is a more interactive agent – it’s dynamic since you can literally program it to expect specific methods, with a specific order or number of calls, and return canned data depending on the preceding conditions. Essentially – it allows you to clearly define what interactions you expect the Mock Object to experience during a test. And then validate the Mock to see if your expectations were correct (pass) or incorrect (fail!). Yep – Mock Objectscarry verifiable assertions about what should happen in a test to the Mock.

This side of Mock Objects, asserting its expected behaviour, let’s you design objects in isolation by Mocking their dependencies – even if those dependencies do not yet exist. This has led their charge into mainstream TDD and BDD as a form of API exploration. As you add Mocks, you are basically designing a class’s interface to its dependencies. The concept of Mock Objects as a design tool is now fairly common if a relatively new idea.

Stubbing With Mockery
Mockery support Stubs in a fairly simple fashion. I remember Travis and I had this argument so many times I lost count , so I divorced the idea of a Stub from a Mock to give Stubs a separate and ultra-simple implementation.

As an aside, Mockery offer two primary starting methods:

1. Mockery::mock()
2. mockery()

Both are interchangeable. For simplicity, and because Travis sold me on the idea, I prefer the function method. The function method is also more anonymous so you’re not constantly creating Stubs using a mock() method (to the confusion of whoever reads your tests). To create a Stub, simply call mockery() and provide it with a class name you want to create, and an array of public methods and their return values. Obviously, the class name cannot exist – if the class does already exist you’ll actually receive a Mock Object (but luckily that too will be confined to a Stub so you won’t notice anything different so it still qualifies as a Stub!):

[geshi lang=php]$stub = mockery(‘Foo’, array(‘print’=>’I am Foo!’));[/geshi]

The new object acts just like a class defined as:

[geshi lang=php]class Foo {

public function print() {
return ‘I am Foo!’;
}

}[/geshi]

Either way, the new object will have one thing for certain – it will be of type Foo, sufficient to pass any class hinting you use in your source code. You can set the configuration method array to return any scalar value or object you want, including other Stubs or even Mock Objects if you’re really feeling fiendishly clever.

With the Stub created, you can proceed to pass it into other objects expecting the interface and return values you configured for that test.

Mock Objects with Mockery
Since Mock Objects are more interactive, they offer a broader API. Like Stubs, they always inherit the class type of the class being mocked, and you can also set return values. Unlike Stubs, you can also set expectations!

So one day, this guy who looks like a Klingon, walks into a web development shop. Sounds like a bad joke, eh? . He wants us to design a Ship Control System but gets nervous when asked about Weapons, Propulsion and Power. Left without a clue about these additional system, he hands over some interface requirements to stick to, and we start with one preliminary test (applying TDD).

[geshi lang=php]class BirdOfPreyTest extends PHPUnit_Framework_TestCase {

public function testWarpFactor8() {
$power = mockery(‘KlingonPower’);
$ship = new KlingonBOP($power);

// set Mock Object expectations
$power->shouldReceive(‘checkForWarp’)->once()->with(8)->andReturn(true);
$power->shouldReceive(‘deduct’)->with(80)->once();

// perform action required
$success = $ship->gotoWarp(8);

// add any necessary assertions?
$this->assertTrue($success);

// verify mock expectations
mockery_verify();
}

}[/geshi]

Since the class KlingonPower doesn’t really exist, we use a Mock Object to figure out how interactions should occur. From those interactions, as the example suggests, it’s a simple matter to actually go an implement the real thing! But since this test focuses on the Bird Of Prey control system, no need to run off yet. We don’t have full specs for a Power system, so we continue using Mocks to explore what its API could be.

Let’s implement the KlingonBOP class to make this test pass:

[geshi lang=php]class KlingonBOP {

protected $power = null;

public function __construct(KlingonPower $power) {
$this->power = $power;
}

public function gotoWarp($factor) {
if ($this->power->checkForWarp($factor)) {
$this->power->deduct($factor * 10);
return true;
}
return false;
}

}[/geshi]

As you can see, using the Mock Object guided us more clearly towards the API of a possible Power system class without requiring we actually implement it. A Stub would also have fit, but would not have provided the API behaviour and expectations we used when implementing the KlingonBOP class.

As for feedback on failures, here some example output from PHPUnit as an example. Reporting details should be improved in future iterations.

PHPUnit 3.3.14 by Sebastian Bergmann.

.E

Time: 0 seconds

There was 1 error:

1) testAddWithFailingMock(AdditionTest)
Mockery_ExpectationException: method get() called incorrect number of times;
expected call 2 times but received 1
This is a really simple example, but hopefully it offers a small taste for the usefulness of both Mock Objects and Stubs.

The Mockery API
Here’s the run down of the current starting points to create a Stub or Mock Object:

mockery('Foo');
Create a new Mock Object with the class name and class type of ‘Foo’.

mockery('Foo', array('set'=>null, 'get'=>foo'));
Create a new Stub with the class name and type of ‘Foo’ defining two public methods and their return values.

mockery('Existing_Class');
Create a new Mock Object with a unique class name but a class type of ‘Existing_Class’. The unique class name is unimportant, but used to generate a Mock which is a subclass of any existing Class, Abstract Class or Interface.

mockery('Existing_Class', 'Custom_Name');
Create a new Mock Object with a class name of ‘Custom_Name’ but a class type of ‘Existing_Class’.

mockery('Existing_Class', array('set'=>null, 'get'=>foo'));
Create a new Stub with a unique class name but class type of ‘Existing_Class’ which effectively acts as a Stub (internally this is a variation on a Mock Object but that detail isn’t that important).

Additional tweaks and mixes of options will follow in the next release shortly.

mockery_verify()
Verify all currently unverified Mock Objects – this also exists as a separate method on every Mock Object for more granularity if needed.

The Mockery Mock Object Expectations API
Every Mock Object expectation starts with the shouldReceive() method. This is also the only non-namespaced method added to all objects, and is therefore a reserved method name. Other methods added dynamically to Mock Objects (or Stubs) are prefixed with “mockery_” to minimise the contamination of the object space with methods you might collide with one day.

A shouldReceive() call returns an instance of Mockery_Expectations which accepts expectations for the given method via a fluent interface, i.e. sequential method calls. These methods include:

never()
Expect the method to never be called. Same as times(0).

zeroOrMoreTimes()
Expect the method to be called zero or more times.

once()
Expect the method to be called exactly once. Same as times(1).

twice()
Expect the method to be called exactly twice. Same as times(2).

times(x)
Expect the method to be called x times.

atLeast()
Set a minimum of times to expect the method to be called by appending one of once(), twice(), or times().

atMost()
Set a maximum of times to expect the method to be called by appending one of once(), twice(), or times().

with(x[, y...])
Expect the list of arguments to be passed to the method.

withAnyArgs()
Expect any arguments including no arguments to be passed to the method.

withNoArgs()
Expect no arguments to be passed to the method.

withArgsMatching(x[, y...])
Expect arguments which, when cast to String, match the given list of Regular Expressions.

andReturn(x[, y...])
Set a return value to be returned from the method call. Multiple parameters set an ordered sequence of returns. In both cases, the last listed value is returned indefinitely to all subsequent calls once any preceeding listed values are used.

andThrow(exception[, message])
Set an Exception class to throw including an optional message.

ordered()
Set an expectation method to be called in a specific order. Each use of ordered() on a Mock Object determines the order, but any method expectations omitting this call remain free to be called at any time.

Conclusion
This is an initial alpha release, so while its hopefully sufficiently feature complete to be useful, its main objective is to illicit feedback! If you want new features, API changes, fixes, or have any ideas or comments whatsoever – please post a comment. You can also fork the git repository on Github.com if you want to make fixes so I can pull them back into my own repo for later distribution in a stable release.

reference : http://blog.astrumfutura.com/2009/03/the-mockery-an-independent-mock-object-and-stub-framework-for-php5/

The Case For Dependency Injection – Part 2

The Recap
In Part 1 of this series, we briefly passed over the concept of Dependency Injection, identifying several injection strategies as below:

1. Constructor Injection
2. Setter Injection
3. Factory Design Pattern

These three patterns have been the mainstay in managing dependencies in PHP source code ever since PHP was capable of handling object oriented programming. However, these strategies can accumulate problems:

1. They require manual management of dependencies when creating new objects.
2. They require users to understand the internal workings of dependencies.
3. They clutter APIs with undocumented methods.
4. They add complexity to tests since manual injections must be performed.
5. They increase the cost of change (manual editing is needed for API changes)
6. They promote static methods in PHP (easier than creating specific objects).

This is not to say, don’t use them! In most circumstances, application of the well known strategies is not only possible but advisable. There is little benefit adding the complexity inherent in Inversion Of Control to simple scenarios.

Inversion Of Control applies to the complex, not the simple.

In isolation, none of these strategies are anything but innocent. But their combined complexity increases as your application grows and networks of classes acumulate. That’s why simple examples of Dependency Injection are doomed to failure – the problems have simple solutions. What we need is something to illustrate that Dependency Injection and Inversion Of Control are applicable to something more concrete, like a fully formed Klingon Bird Of Prey with all the bells and whistles!

[geshi lang=php]class Ship_Klingon_BirdOfPrey {

// arrays indicate multiple object instances are required
protected $warpCore = null;
protected $disruptorBanks = array();
protected $warpEngine = null;
protected $shields = array();
protected $crew = null;
protected $shipsLog = null;
protected $computer = null;
protected $sensors = array();

// …

}[/geshi]

Are you getting the picture yet? Consider any application based on a complicated process. You may have dozens of objects working in concert towards a single goal. Kapla!

To create the client object, a Bird Of Prey, you need to inject every service object it requires since they are needed. In a simple use case, however, the user only wants a damn ship! They don’t care about the components unless they have a need to customise some internal operation. In this scenario, the Factory option might work. Using the Factory, we need to cover off on the testing piping using static means. We could just use any available setters or constructor parameters – but then our tests are going to be huge whenever a new Ship is needed.

But let’s dig deeper! How will we use the Ships Log? Every component will need to report it’s status there – so the Log is a service to the Ship, and to every other sub-system. Let’s double our Factory method length. Now, what if the computer needs to liase with the Sensors, acquire a Target via the Computer, and order the Disruptor Banks to fire? So the Sensors, Log, Disruptor Banks and possible Crew complement become needed by the Computer. Let’s double…nay…quadruple everything.

Next we decide to give the Computer a database, along with the Log, the Ship and maybe the Crew. Or we realise half this stuff are Models anyway, so give them all databases to play with!

Excuse me while I sit in a corner and cry…I only wanted a bloody ship! Why are making me do all this?

The Service Locator Pattern
Complex problems can still have simple solutions, and the Service Locator has long superceded the Factory when the going gets a bit tougher. Manually handling complex dependencies is insane (on all levels), so a little configuration can be handy.

A simple Service Locator is used like a map. If an object needs a specific service object, it refers to the Locator to retrieve a copy. You can embellish the system in any number of ways using keywords, tagging, URLs, and even utilise concrete Factories as needed, but the simplest Service Locator is a plain old array (which is also the simplest Registry):

[geshi lang=php]$locator = array(
‘log’ => new Ship_Log,
‘warpCore’ => new Ship_WarpCore,
‘computer’ => new Ship_Computer,
‘warpEngine’ => new Ship_WarpEngine,
// …
);[/geshi]

If you pass this locator to the Bird Of Prey, and let the BOP pass it to all other service objects it retrieves from the Locator array, then you can cut out the complex web of dependencies from manual management and let them all refer to the Locator instead. You can even adapt the Locator in tests to return Mock Objects. Aside from object lookup, you can also integrate configuration so the located objects can be constructed correctly.

So where are the negatives? Well, now everything needs to know about this super Service Locator, since otherwise objects couldn’t find their dependencies. It also ignores the order of creation – some objects need to be created before others or the more circular dependencies will fail to be available. If we try to create the Computer, but not the Log, then we can’t give the Computer a Log and the locator will fail. This would necessitate…manual intervention. We’d need to manually track and switch around code across numerous classes to ensure the order of creation is executed correctly. This is far from ideal, so while a Service Locator is a highly useful tool in the toolbox, orchestrating the dependency web needs something more.

The Next Obvious Evolution
As we gradually evolve from simple injection, the Service Locator was revealed as a capable, lightweight, flexible solution. It’s primary problem was dependency resolution. Rather than scatter this across all those classes, why not simply centralise them in the Service Locator itself? It’s at this point we shift from a Locator, to a simple Dependency Injection Container (ah, finally the Container term ) and leave our poor overburdened objects free of this distraction to focus solely on their roles.

Here’s an ultra simple IOC container:

[geshi lang=php]class DIContainer {

protected $_data = array();

public function set($name, $value) {
$this->data[$name] = $value;
}

public function get($name) {
if (isset($this->data[$name])) {
return $this->data[$name];
}
return $this->call(‘get’.ucfirst($name));
}

protected function getLog() {
$log = new Ship_Log($this->get(‘logfile’));
$this->data['log'] = $log;
return $log;
}

protected function getWarpCore() {
$warpCore = new Ship_WarpCore();
$this->data['warpCore'] = $warpCore;
$warpCore->setLog($this->get(‘log’));
}

protected function call($method) {
return $this->{$method}();
}

// …

}[/geshi]

This new Container class is a really simple implementation of a DI Container which assumes all client objects will utilise the exact same service objects. Like a Service Locator, you can use it to grab registered objects. However, it is written to also determine the order of creation of any object requested, then create it, and finally return it.

[geshi lang=php]$container = new DIContainer;
$container->set(‘logfile’, ‘/tmp/shiplog’);
$warpCore = $container->get(‘warpCore’);[/geshi]

A completed version could utilise the simple Strategy Pattern so you could have a single container for specific Model types accepting configuration options for everything the Container needs.

[geshi lang=php]$container = new DIContainer_Ship;
$container->set(‘type’, ‘Klingon BOP’);
$container->set(‘logfile’, ‘/tmp/shiplog’);
$container->set(‘db_type’, ‘mysql’);
$container->set(‘ship_db_table’, ‘ships’);
$container->set(‘capacity’, ’300′);
$ship = $container->get(‘ship’);[/geshi]

Of course, let’s not let this get away free . The obvious flaw is the amount of manual programming it still needs, even though it’s drastically reduced the overall code need by avoiding code duplication and centralising this task. While the dependency management is cool, the wiring is all manual. Adding the element of automation to the new Container concept with a little Reflection and typehinting could go far. Adding cloning might speed up the creation of Containers by allowing minor configuration tweaks. Adding object replacement would allow for Mock/Stub insertion. I’m sure you can think of lots of added elements to make something easier to utilise.

Conclusion
We’ve finally met the simplest kind of IOC possible. In Part 3, we’ll move outside this simple and flawed implementation, and take a look at the forms of IOC frameworks living in the wild whether they be PHP, Python or Ruby. Frameworks should, in theory, make these Containers a lot easier to setup and maintain in a more strucured form that removes the need for customising classes. Instead mixing convention with some configuration, and taking advantage of Reflection, should produce more maintainable and testable options.

reference : http://blog.astrumfutura.com/2009/03/the-case-for-dependency-injection-part-2/

The Case For Dependency Injection – Part 1

It’s been years since I first met the concept of Dependency Injection, and despite the influx of proposals, actual libraries, and spotty writing on the topic, it remains elusive in PHP. Well, with my newfound freedom to bang on my keyboard and commit real time to development and writing, I’m making this provocative and sometimes accusatory entry to perhaps spark some progress.

What is Dependency Injection?
Explaining Dependency Injection is not that hard:

[geshi lang=php]class KlingonBOP {

public $power = null;

public function __construct() {
$this->power = new WarpCore();
}

public function toWarp($factor) {
if($this->power->has($factor*10)) {
return true;
}
return false
}

}[/geshi]

This KlingonBOP class can be thought of as a client which depends on services (other objects) in order to function (the analogy is really to assist understanding the relationships), like the WarpCore object which is a service to the KlingonBOP client.

Now consider how write a unit test for this class. Unit testing works by testing classes in isolation from their dependencies – this rules out any unintended interference from other classes (i.e. a cascading set of failures), and also removes the need to actually develop the service/dependent class right now.

In the code above, we have an obvious problem – in a test, we cannot replace the WarpCore object since it is explicitly instantiated in the constructor. By replace, I mean write the tests using a Mock Object or Stub instead of a real WarpCore instance, something which has predictable constant return values.

Dependency Injection Strategies
Dependency Injection is all about how to inject these service objects into the client objects, making use of them in such a way they can be easily swapped by any other source code (not just tests!). Assuming you’re with me so far, you can identify the two most obvious Dependency Injection strategies:

1. Pass the service to the constructor as a parameter (contructor injection).
2. Pass the service to a class mutator/setter method (setter injection).

Using either of these, we can write a nice isolated unit test such as:

[geshi lang=php]require ‘Mockery/Framework.php’;

class KlingonShipTest extends PHPUnit_Framework_TestCase {

public function testAllowsWarpIfSufficientPowerAvailable() {
$ship = new KlingonBOP(
mockery(‘WarpCore_Stub’, array(‘toWarp’, ‘true’))
);
$this->assertTrue($ship->toWarp(1));
}

}[/geshi]

or

[geshi lang=php]require ‘Mockery/Framework.php’;

class KlingonShipTest extends PHPUnit_Framework_TestCase {

public function testAllowsWarpIfSufficientPowerAvailable() {
$ship = new KlingonBOP();
$ship->setWarpCore(
mockery(‘WarpCore_Stub’, array(‘toWarp’, ‘true’))
);
$this->assertTrue($ship->toWarp(1));
}

}[/geshi]

Now we can edit the class for the constructor injection or setter injection strategies as appropriate…

These two DI options are often called “Manual Dependency Injection” or “Construction By Hand”, a reference to the fact we are manually constructing and handing services to client objects. Every single service object gets the manual treatment, and that’s the norm in most PHP source code. It’s a primary underpinning of the concept of composition in OOP afterall.

So what’s the problem? It’s manual!

Anything manual has two facets. First, you need to know how to do it by hand (RTFM ). Secondly, you better do it right and add more tests. Third, it must be duplicated everywhere so you better not forget how to do it…ever!

Being manual isn’t all bad though, most objects need one, two or at most three service objects. It’s messy in large doses but quite manageable. It’s when things become unmanageable that it becomes interesting because its at that point all those fluffy ideals like unit testing and decoupling are thrown out the window (I prefer to flush mine down the drain, but everyone’s a critic).

The most likely outcome of the manual approach is the duplication of all that object wiring. What happens if the API changes? You need to manually re-edit all those instantiations and API calls across the application(s). When they break BC for the next version? Manually edit…again. The other is requiring in-depth knowledge of every detail including how internal objects are utilised. Besides adding additional onus on people to refer constantly to the manual, or far worse – the source code itself, it ignores the concept that only the outer public API has real value – the rest is just an annoying burden of knowledge weighing us down. I don’t know about other programmers, but I never bother to memorise anything but a library’s basics. Why should I? Programmers are supposed to be supported in their group laziness .

Let’s emphasise everything so far by moving onto Dependency Injection strategy three – the Factory and Abstract Factory design patterns. You didn’t really think I forgot about them, did you? .

Both patterns have simple goals, to centralise the creation logic of objects so they are easier to reuse, and reduce code duplication across your source code where the created objects are needed. Typically they wind up being class methods. Annoying, irksome, untestable, static class methods.

But let’s not go overboard, we can make the Factories into specific classes (they have a separate role afterall!) with public methods instead (PHP is obsessed with those bloody static methods so the trail ends there usually) which instantly makes them amenable to Dependency Injection strategies 1 and 2 (and allows you to mock/stub the factory object in tests). This does wonders, and then you find out about the punchline…

Factories add three layers of complexity, not two, so you now need to double up on Mock Objects and stubs in tests. To utilise Mock Objects in place of the dependent object (created by the Factory class for the dependee), you need a way to force the Factory to send out mocks or stubs in place of creating an actual new object. At this point you start scratching your head, so you throw in a setter which you realise won’t work (Factories don’t remember what they create, they just return the end product immediately), and perhaps toe across the line and apply the Registry pattern to make Factories hold a static memory of any mock/stub you need it to use instead of creating a new one. Sometimes you’ll simply do away with the Factory (basically accepting the cost of its loss in added complexity to the end user!) and fall back on setter/constructor injection.

We’ll assume that the tactic used is the simpler option – stub the Factory class, and set a canned response which is actually another mock/stub of the object being created. Twice the mocks, unless it’s a static method (yes, I am hating static methods way too often in this post ).

If there is such a thing a Singletonitis, Factoryitis is a close relative. A simple Factory is great, but then you realise the Factory isn’t creating one single universal object, it’s dynamically creating variations based on passed parameters, config files, or via multiple public methods for hand coded variations. That’s a lot of surrounding code, and if your original duplication varied on the inputs, a Factory buys you little benefit apart from centralising all that muck in one place where it builds up and grows into complex monolithic code blocks. And how do you even test the Factory anyway? You already tested each object it creates, so you duplicate that to maintain some sanity?

Note: You can test even static factories, once you remember to clean them up in reverse. Technically though, you still can’t mock or stub the buggers without adding test wiring – extraneous methods and properties only used by tests.

This raises a spectre of a problem – if a factory is not easily tested, and we sacrifice it to fall back on more testable injection strategies, we’re lost the benefits of the factory in reducing complexity to the end user and code duplication across the source. Can we take back control?

Dependency Injection: The Inversion Of Control
So we know the basics, inherently, without really calling them Dependency Injection outright, but Dependency Injection is also its own strategy by combining facets of all these strategies into a single comprehensive solution. Something that makes testing, composition, and configured creation easy without all the nasty consequences (well, so it claims – judge for yourself). From now on I’ll refer to this overarching strategy simply as Inversion Of Control (IOC). Often IOC is used interchangeably with DI which can be confusing, so bear in mind DI is IOC plus the original injection strategies I’ve mentioned so far.

IOC makes a few assumptions I’m already pushed around. It needs to make testing easy. It needs to avoid manual coding of dependencies. It also needs to remain ignorant of the dependencies until it’s told what to do. It also assumes all objects used in object creation remain loosely coupled (one of the cardinal sins often used in opposition to DI) and abide to API contracts (code to the interface, not the implementation!). In fact it presumes a common deferred approach – objects expect their dependents to be handed to them, but they never actively seek those dependencies by themselves. A sort of don’t call me, I’ll call you approach on the part of dependents.

The primary member of any IOC strategy is the Injector. You might see DI frameworks referring to the Container more often, but we’ll get around to why its called a Container – in there somewhere is always an Injector. As the name suggests, Injectors exist to inject dependents into dependees. Much as you do manually in the previous DI strategies.

Anyone familiar with objects will realise its role quite easily – the Injector creates all service objects with all of their own dependencies injected (preferably without creating an infinite loop though ) and injects those service objects into the client object being created before returning the client object for use. We’ll explore the concept and approach in another post soon, assess the current state of play in PHP of Dependency Injection, and see where DI can be dragged into actual source code in a useful way.

Until next time…

reference:http://blog.astrumfutura.com/2009/03/the-case-for-dependency-injection-part-1/

wibiya widget