簡體   English   中英

unit test一個創建對象的方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM