2015-01-16 2 views
1

Я все еще довольно новый с PHPUnit, и я пытаюсь выяснить, как наилучшим образом проверить методы, как показано в 3-м классе.Доступ к базе данных из теста PHPUnit

Я понимаю, как работают макетные базы данных (я думаю), поскольку они могут возвращать значения на основе ввода, из файла XML и т. Д. Я не уверен, как предоставить данные для третьего примера, когда SQL-запросы выполняются внутри самих методов.

Я пытаюсь проверить код, который обращается к информации из БД и выполняет на ней операции. В настоящее время нет способа подкачать данные DB (например, массивы) этим методам.

Вопрос: Каков наилучший способ предоставления данных методу, который обрабатывает все его SQL-запросы внутренне?

<?php 
class ThisMakesSense { 

    public function checkPassword($original, $hash) { 
     return (md5($original) == $hash); 
    } 

} 


class ThisMakesSenseTest { 

    public function testCheckPassword() { 
     $tms = new ThisMakesSense(); 
     $data = array('[email protected]' => 'password1', '[email protected]' => 'password2');   
     foraech ($data as $email => $password) { 
      $hash = $this->mockDB()->doStuff()->getPasswordHashByEmail($email); 
      $this->assertTrue($tms->checkPassword($password, $hash), "Password for {$email} is invalid"); 
     } 

     $tms->checkPassword($password, $hash); 
    } 
} 

/* The '$this->_db' object is basically an OOP way of using the 
* mysql_* /mysqli_* functions. Replacing it is not an option 
* right now. 
*/ 
class DontUnderstand { 
    public function checkPassword($email, $password) { 
     $this->_db->query("SELECT password_hash FROM users WHERE email = '{$email}'"); 
     $row = $this->_db->fetchAssoc(); 
     return (md5($password) == $row['password_hash']); 
    } 
} 


class DontUnderstandTest extends PHPUnit_Framework_TestCase { 
    public function testCheckPassword() { 
     $du = new DontUnderstand(); 
     $data = array('[email protected]' => 'password1', '[email protected]' => 'password2'); 

     foreach ($data as $email => $pass) { 
      $this->assertTrue($du->checkPassword($email, $pass), "Password for {$email} is invalid"); 
     } 
    } 
} 

(Для того, чтобы спасти кому-то неприятности, комментируя, что md5 и запросов методы являются лишь для простого примера)

ответ

1

Я не уверен, что это лучший подход, но вот мой путь. Он основан на предположении о классе, который соединяется внутри с базой данных и одной таблицей. Доступ осуществляется через INSERT, UPDATE, DELETE, SELECT и т.п., поэтому нет сложных JOINs или UNION. Другое предположение заключается в том, что я устанавливаю базу данных один раз (а не как часть процедуры тестирования) до запуска phpunit. Я посмотрел на расширение базы данных PHPUnit, но она показалась мне слишком громоздким, чтобы использовать здесь, так что я быстро высмеял это:

class UserProfileTest extends PHPUnit_Framework_TestCase { 

    protected static 
    $options, 
    $dbHandle;  

    public static function setUpBeforeClass() { 
    self::$options = array(
       'dbHostName' => 'localhost', 
       'dbUserName' => 'tester', 
       'dbPassword' => 'pw4tester', 
       'dbName' => 'test', 
       'dbTableName' => 'Test', 
       );    
    self::$dbHandle = new mysqli(self::$options[ 'dbHostName'], self::$options[ 'dbUserName'], self::$options[ 'dbPassword'], self::$options[ 'dbName']); 
    if(self::$dbHandle->connect_errno) 
     exit('Error: No DB connection.'); 
    } 

    protected function fillDb() { 
    $query = 'INSERT INTO ' . self::$options[ 'dbTableName'] . ' VALUES (default,"foo","bar",7)'; 
    if(!self::$dbHandle->query($query)) 
     exit('Error: Could not fill DB.'); 
    } 

    protected function setUp() { 
    // always start a TC with empty DB 
    $query = 'DELETE FROM ' . self::$options[ 'dbTableName']; 
    if(!self::$dbHandle->query($query)) 
     exit('Error: Could not empty DB.'); 
    } 

    // -- test -- 
    public function testGetNumberOfProfiles() { 
    $profileMgr = new UserProfile(self::$options); 
    $this->assertEquals(0, $profileMgr->getNumberOfProfiles()); 
    $this->fillDb(); 
    $this->assertEquals(1, $profileMgr->getNumberOfProfiles()); 
    $this->fillDb(); 
    $this->assertEquals(2, $profileMgr->getNumberOfProfiles()); 
    } 

Таким образом, при подключении к БД, когда создается экземпляр класса (setUpBeforeClass), и опорожнить таблицы перед каждым тестовым регистром (в setUp). Существует вспомогательная функция, которая вставляет строку в таблицу; он вызывается при необходимости.

Смежные вопросы