2012-03-22 3 views
2

PHP PDO Singleton Class:Как проверить PHP PDO Singleton Class?

<?php 

require_once('app/config.php'); // Require constants HOST, DATABASE, USER, PASSWORD 

/* 

dbConnection class. 

Manages connections to and operations on the database. Call dbConnection::getInstance() to return an instance. 
Prepare your statements by calling prepareQuery() on the object 

Attribute list: 

$instance: 
> Static self instance to manage database resource 

$connection: 
> Holds connection resource 

$sth: 
> Statement handler variable. Handles SQL statements. 
_______________________________________________________________________________________________________________ 

Method list: 

getInstance(): 
> Creates or returns existing connection to the database 

prepareQuery(): 
> Prepares the $sth variable for execution. 

bindParameter(): 
> Binds parameters to the $sth variable. 

numRows($query): 
> Returns the number of returned from a query 

runQuery(): 
> Executes the current statement on the database 

fetchRow(): 
> Executes the current statement then returns an associative array 

fetchObj($className, $parameters = NULL): 
> Executes the current statement and returns an object of your specification. Also takes additional parameters to pass to the object's constructor. 


*/ 

class dbConnection 
{ 
    private static $instance = NULL; 
    private $connection; 
    private $sth; 

    function __construct() 
    { 
     $this->connection = new PDO('mysql:host=' . HOST . ';dbname=' . DATABASE, USER, PASSWORD); 
    } 

    function getInstance() 
    { 
     if (self::$instance == NULL) 
      self::$instance = new dbConnection(); 
     return self::$instance; 
    } 

    function prepareQuery($query) 
    { 
     $this->sth = $this->connection->prepare($query); 
    } 

    function bindParameter($number, $value) 
    { 
     $this->sth->bindParam($number, $value); 
    } 

    function numRows() 
    { 
     try 
     { 
      $this->sth->execute(); 

      $count = $this->sth->rowCount(); 
      return $count; 
     } 
     catch(PDOException $e) 
     { 
      echo __LINE__.$e->getMessage(); 
     } 
    } 

    function runQuery() 
    { 
     try 
     { 
      $this->sth->execute() or print_r($connection->errorInfo()); 
     } 
     catch(PDOException $e) 
     { 
      echo __LINE__.$e->getMessage(); 
     } 
    } 

    function fetchRow() 
    { 
     try 
     { 
      $this->sth->setFetchMode(PDO::FETCH_ASSOC); 
      $this->sth->execute(); 
      return $this->sth; 
     } 
     catch(PDOException $e) 
     { 
      echo __LINE__.$e->getMessage(); 
     } 
    } 

    function fetchObj($className, $parameters = NULL) 
    { 
     try 
     { 
      $this->sth->setFetchMode(PDO::FETCH_CLASS, $className, $parameters); 
      $this->sth->execute(); 
      return $this->sth; 
     } 
     catch(PDOException $e) 
     { 
      echo __LINE__.$e->getMessage(); 
     } 
    } 
} 
?> 

Как проверить одиночки? Возьмите объект за раз, который закрыт, когда вы закончите с объектом в конце.

+0

В случае, если речь идет не о PHPUnit, пожалуйста, проясните, что вы пытаетесь проверить в первую очередь. Ваше описание выше в настоящее время очень сложно понять. – Gordon

ответ

5

I think you are misapplying the Singleton pattern here.

Тем не менее, тестирование Singletons возможно. Цитирование Testing Code that uses Singletons

PHPUnit имеет механизм резервного копирования/восстановления для статических атрибутов классов.

Это еще одна особенность PHPUnit, которая упрощает тестирование кода, который использует глобальное состояние (которое включает, но не ограничивается, глобальные и суперглобальные переменные, а также статические атрибуты классов).

Также см http://www.phpunit.de/manual/current/en/fixtures.html#fixtures.global-state

@backupStaticAttributes аннотация, что обсуждается в section called “@backupStaticAttributes” может быть использован для управления резервного копирования и восстановления для статических атрибутов. В качестве альтернативы, вы можете указать черный список статических атрибутов, которые должны быть исключены из резервного копирования и восстановления, как этот

Так что если вы хотите, чтобы отключить резервную копию, вы могли бы сделать

class MyPdoTest extends PHPUnit_Framework_TestCase 
{ 
    protected $backupStaticAttributesBlacklist = array(
     'dbConnection' => array('instance') 
    );  

    // more test code 
} 

Рекомендуем также см. главу на странице Database Testing

+0

Можете ли вы протестировать его без рамки «PHPUnit_Framework_TestCase »? –

+0

@Nerujua Умеешь ли ты? Ну, я так думаю, но это не имеет большого смысла. PHPUnit - это стандарт defacto для тестирования PHP-кода, и когда вы спрашиваете «как протестировать этот код», люди предполагают, что вы ссылаетесь на модульное тестирование с помощью PHPUnit. Поэтому, если вы задаете вопрос не о PHPUnit, вам нужно будет уточнить, что такое ваше определение «тестирование». – Gordon

1

Синглтоны - плохая новость, как я уже объяснил here.

В частности, на ваш вопрос, синглтоны чрезвычайно сложны для модульного тестирования. Это одна из причин, почему они плохие новости.

Вместо этого использовать .

EDIT TO ADD:

Я полагаю, вы могли бы написать набор модульных тестов, где каждый испытуемый блок находится в своем собственном наборе тестов, и все тестовые наборы установлены для запуска в отдельном процессе. Это должно изолировать каждый модульный тест от других.

Производительность была бы ужасной, хотя, и вам действительно лучше просто использовать подход DI.

(я предполагаю, что вы используете для модульных тестов здесь)