2012-03-22 50 views
2

PHP PDO Singleton Class:如何测试PHP PDO Singleton类?

<?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 2012-03-22 18:38:14

回答

5

I think you are misapplying the Singleton pattern here.

然而,测试单身是可能的。引用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 ”的情况下测试它吗? – 2012-03-22 15:42:12

+0

@Nerujua你能吗?那么,我想是这样,但没有多大意义。 PHPUnit是测试PHP代码的事实标准,当您询问“如何测试此代码”时,人们会认为您指的是使用PHPUnit进行单元测试。所以如果你的问题不是关于PHPUnit的话,你必须澄清你的“测试”定义是什么。 – Gordon 2012-03-22 17:05:22

1

单身人士是坏消息,因为我已经解释了here

更具体到你的问题,单身人士是非常困难的单元测试。这是他们是坏消息的原因之一。

改为使用

编辑补充:

我想每个单元测试是在自己的测试套件,所有的测试套件被设置为在一个单独的进程中运行,你可以写一组单元测试。这应该将每个单元测试与其他测试隔离开来。

虽然性能会很糟糕,但您最好使用DI方法代替。

(我假设你正在使用为单元测试这里)