![](/img/trans.png)
[英]How to unit test a method that creates a Zend\Db\Sql\Sql object?
[英]unit test a method that creates an object
我正試圖讓我的頭部單元測試 ,還有一件我需要找到的拼圖。
我要做的是為以下代碼編寫測試。 在這種情況下,我有一個非常簡單的前端控制器(用PHP編寫)。
class frontController
{
public function routeRequest($oRequest)
{
$sClassname = $oRequest->getController();
$sMethod = $oRequest->getAction();
$oController = new $sClassname();
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
我遇到的問題是因為代碼創建了新對象 。 我可以輕松地模擬請求對象,以便我可以嚴格控制它在我的測試用例中實際執行的操作。 我不確定用測試雙重替換控制器的最佳方法。
IBM的這篇文章建議使用工廠方法來創建我的控制器,然后用一個用於測試的特定類來覆蓋它:
class frontController
{
public function routeRequest($oRequest)
{
$sMethod = $oRequest->getAction();
$oController = $this->createController($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
protected function createController($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
然后測試可能是這樣的:
class testFrontController extends frontController
{
public function setMockController($oMockController)
{
$this->oMc = $oMockController;
}
protected function createController($oRequest)
{
return $this->oMockController;
}
}
(注意這不是文章所說的,但我認為如果它這樣做對我來說最有用)
另一個解決方案可能是創建另一個創建控制器的類。 這將是frontController的依賴類。 這樣我就可以在測試過程中用test double替換工廠/創建類。 像這樣的東西:
class frontController
{
public function routeRequest($oRequest, $oControllerFactory)
{
$sMethod = $oRequest->getAction();
$oController = $oControllerFactory->create($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
class controllerFactory
{
public function create($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
我想依賴注入可以在前端控制器構造函數中處理,或者通過setter而不是實際“route”方法的參數來處理。
我想我更喜歡選項2。
這兩種方法中的任何一種都是正確的測試方法嗎?
(也許“好方法”會更好的在這里!)
關於選項1與選項2的任何想法或建議都表示贊賞或確實有任何替代方案 記住 - 關鍵是如何測試一個對象本身創建其他對象作為其執行的一部分。
謝謝!
你可能會發現這篇文章很方便。
它討論了如何將對象創建與應用程序的實際運行分開。
我通常認為工廠在這種情況下是一件好事。 除了可交換性方面,它還意味着工廠可以存儲正在創建的對象所需的其他參數,數據或依賴項,因此實際請求新對象的對象不必知道任何有關它們的信息。 ..
你不想使用真正的控制器而是模擬,對嗎?
在我看來,實現這一點的最簡單方法是將請求子類化,以便返回MockController的名稱。
我假設您已經考慮過您的斷言,以便確定您正在測試的目標。 請記住,單元測試將測試您的方法的返回,在這種情況下,這是$ oResponse(無論這可能是什么)。 因此,您的測試斷言將基於此返回值。 由於我不知道您的代碼片段的返回值是什么,因此我只能演示您可以完成的示例。
我建議您使用PHPUnit進行測試,因為它似乎是PHP imho最完整的軟件包(許多人都是SimpleTest的粉絲,以及他們自己的每個人)。
它看起來像這樣(請注意,為簡潔起見,我省略了包含。請閱讀PHPUnit文檔以獲取更多信息):
class AimTest extends PHPUnit_Framework_TestCase{
private $_controller = null;
private $_request = null;
public function setUp(){
$this->_controller = new frontController();
//what does this object's type?
$this->_request = new requestObject();
}
public function testObjectCreation(){
/*
* note, that this is only one of several assertions that could
* be made depending on the return value
*/
$return = $this->_controller->routeRequest($this->_request);
//tailor to what you expect your output to be
$this->assertTrue($return == "my expected output");
}
希望我沒有完全按照你聲明的目的錯過這個標記。 故事的道德是你只能測試你的方法返回的內容。 如果要從方法測試對象實例化,請對實例化后返回該對象的方法使用instanceof PHP函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.