如何测试PHP PDO Singleton类?

时间:2012-03-22 10:36:21

标签: php mysql singleton phpunit

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();
        }
    }
}
?>

如何测试单身? 一次取一个对象,当你在最后完成对象时关闭它。

2 个答案:

答案 0 :(得分: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

  

section called “@backupStaticAttributes”中讨论的@backupStaticAttributes注释可用于控制静态属性的备份和还原操作。或者,您可以提供要从备份和还原操作中排除的静态属性的黑名单,如此

因此,如果你想禁用备份,你可以

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

    // more test code
}

另请参阅Database Testing

一章

答案 1 :(得分:1)

单身人士是坏消息,正如我已经解释过here

更具体地说,你的问题,单身人士很难进行单元测试。这是他们为什么是坏消息的原因之一。

请改用

编辑添加:

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

虽然性能会很糟糕,但你最好只使用DI方法。

(我假设你在这里使用进行单元测试)