2017-01-26 48 views
0

我正在嘗試使用PHPUnit編寫一個PHP項目的unittest。該項目主要使用SQL數據庫。PHP和SQL單元測試

我有使用SQL的任何函數,我不知道如何開始編寫測試。我有一個問題找到要做什麼測試,因爲他們都使用SQL,其中大多數不返回任何東西,但只是操縱數據庫和會話變量。

這是嘗試用於創建測試之一:

<?php 
    require_once '../../test/admin/admin.php'; 

    class checkIsAdminTest extends PHPUnit_Framework_TestCase { 
     private $ID = '123456789'; 
     private $Class = 0; 
     private $Pass = 'Aa12345678'; 
     private $First = "Bla"; 
     private $Last = "Bla"; 
     private $Email = "[email protected]"; 

     protected function setUp() { 
      parent::setUp(); 

      $servername = "localhost"; 
      $username = "root"; 
      $password = ""; 

      $dbname = 'trivia'; 
      $conn = mysqli_connect($servername, $username, $password, $dbname); 

      $sql = "INSERT INTO `users` (`ID`, `Class`, `Password`, `First`, `Last`, `Email`) VALUES ('" . $this->ID . "', '" . $this->Class . "', '" . sha1($this->Pass) . "', '" . $this->First . "', '" . $this->Last . "', '" . $this->Email . "');"; 
      mysqli_query($conn, $sql); 

      session_start(); 
      $_SESSION["ID"] = $this->ID; 
     } 

     protected function tearDown() { 
      parent::tearDown(); 
     } 

     public function __construct() { 
     } 

     public function testCheckIsAdmin() { 
      $this->assertEquals($this->Class == 0 ? False : True, checkIsAdmin()); 
     } 
    } 
?> 

功能檢查是否命名的記錄的字段「類」的一個表中的谷「用戶」是0或1,返回如果是1,則爲「真」,否則爲假。

回答

1

你遇到的這個問題說明了你當前的設計存在一個更大的問題(即「代碼味道」),即你有一個混合兩個問題的類,即存儲(mysql的東西)和業務邏輯本身。這些應該是單獨的關注點,因此應該是單獨的類,並且您應該考慮如何解決這兩個問題(然後,您應該使用Dependency Injection將這兩個問題結合在一起,方法是將數據庫對象通過構造函數論據)。

一旦你設法將它們分開,你將能夠分別將這兩個模塊分開。對於實現業務邏輯的類,您可以使用mock object來代替SQL類,您可以在其中控制被測試對象接收到的響應,而不必依賴真實的數據庫,該數據庫可能具有或可能沒有適合測試的正確數據它。

單元測試的一個重要方面是,您必須能夠將代碼劃分爲可以儘可能獨立測試的不同單元。這要求您比平時更多地考慮應用程序的體系結構。這不僅具有可測試性的優點,而且還使您的代碼更加靈活和適應性更強。例如,如果您決定在數據庫和業務對象之間添加緩存層,該怎麼辦?使用模塊化代碼時,編寫一個對象的相對容易,該對象可以像數據庫類一樣操作,但維護自己的內部緩存,只在請求的數據不在緩存中時纔將請求傳遞給實際數據庫。這對客戶類應該是不可見的。如果您決定用Google Cloud中的BigTable替換MySQL,情況也是如此。