PHPUnit 4.8模拟mysql数据库接口

PHPUnit 4.8模拟mysql数据库接口,php,mysql,unit-testing,phpunit,Php,Mysql,Unit Testing,Phpunit,下午好 我有一堆使用旧的mysql库的遗留代码(mysql\u query($sql)),我正试图用PHPUnit对其进行测试(4.8是最新版本,由于各种原因将在服务器上运行) 有人知道如何模拟此数据库连接,以便在运行预定查询时返回预定结果吗?我尝试过使用getConnection()(根据此处的文档:)但没有效果 例如,我有一门课: class Raffle { ... public static function loadAll($filter=""){ //

下午好

我有一堆使用旧的
mysql
库的遗留代码(
mysql\u query($sql)
),我正试图用PHPUnit对其进行测试(4.8是最新版本,由于各种原因将在服务器上运行)

有人知道如何模拟此数据库连接,以便在运行预定查询时返回预定结果吗?我尝试过使用getConnection()(根据此处的文档:)但没有效果

例如,我有一门课:

class Raffle {
    ...
    public static function loadAll($filter=""){
        //$filter = mysql_real_escape_string($filter); // protect against SQL injection
        $raffles = []; // the array to return

        $sql = "SELECT * FROM raffles $filter;"; // include the user filter in the query
        $query = mysql_query($sql);

        //echo mysql_error();

        while($row = mysql_fetch_assoc($query)){
            $raffles[] = Raffle::loadFromRow($row); // generate the raffe instance and add it to the array
        }
        return $raffles; // return the array
    }
    ...
}
(调用
mysql\u connect()
是在一个名为
db.php
的文件中完成的,该文件加载到每个需要的页面上,而不是类文件本身。)


提前感谢。

对于其他陷入这种情况的人,我发现构建一个包含函数api回退的PDO模拟,允许我将代码迁移到一个基于OO的可测试模型,同时仍在幕后使用旧的
mysql

例如:

// the basic interfaces (function names taken from PDO
interface DBConnAdapter {
    public function query($sql);
}
// since PDO splits connections and statements the adapter should do the same
interface DBQueryAdapter {
    public function num_rows();
    public function fetch_assoc();
}
...
class DBAdapter implements DBConnAdapter {

    public function query($sql){
        $query = mysql_query($sql); // run the query using the legacy api
        return $query ? new QueryAdapter($query) : false; // return a new query adapter or false.
    }

}
...
// an example of a basic mock object to test sql queries being sent to the server (inspired by mockjax :-) ) 
class DBMock implements DBConnAdapter {

    public $queries = []; // array of queries already executed
    public $results = []; // array of precomputed results. (key is SQL and value is the returned result (nested array))

    public function query($sql) {
        if($this->results[$sql]){
            $query = new DBQueryMock($sql, $this->results[$sql]); // a mock of PDOStatement that takes the sql it ran and the results to return
            $queries[] = $query; // add the query to the array
            return $query; // return the query
        }
        return false; // we do not know the statement so lets pretend it failed
    }
    // add a result to the list
    public function add_single_result($sql, $result){
        // check if the index was set, if not make an array there
        if(!isset($this->results[$sql])) $this->results[$sql] = [];
        // add the result to the end of the array
        $this->results[$sql][] = $result; 
        // return its index
        return count($this->results[$sql]) - 1;
    }
}
诚然,这不是一个理想的解决方案,因为它需要修改代码以支持适配器对象,并删除一些功能(例如
mysql\u real\u escape\u string
),但它确实有效


如果您有更好的解决方案,请分享:-)谢谢

对于其他陷入这种情况的人,我发现构建一个包含函数api回退的PDO模拟让我能够将代码迁移到一个可测试的基于OO的模型,同时仍然使用旧的
mysql

例如:

// the basic interfaces (function names taken from PDO
interface DBConnAdapter {
    public function query($sql);
}
// since PDO splits connections and statements the adapter should do the same
interface DBQueryAdapter {
    public function num_rows();
    public function fetch_assoc();
}
...
class DBAdapter implements DBConnAdapter {

    public function query($sql){
        $query = mysql_query($sql); // run the query using the legacy api
        return $query ? new QueryAdapter($query) : false; // return a new query adapter or false.
    }

}
...
// an example of a basic mock object to test sql queries being sent to the server (inspired by mockjax :-) ) 
class DBMock implements DBConnAdapter {

    public $queries = []; // array of queries already executed
    public $results = []; // array of precomputed results. (key is SQL and value is the returned result (nested array))

    public function query($sql) {
        if($this->results[$sql]){
            $query = new DBQueryMock($sql, $this->results[$sql]); // a mock of PDOStatement that takes the sql it ran and the results to return
            $queries[] = $query; // add the query to the array
            return $query; // return the query
        }
        return false; // we do not know the statement so lets pretend it failed
    }
    // add a result to the list
    public function add_single_result($sql, $result){
        // check if the index was set, if not make an array there
        if(!isset($this->results[$sql])) $this->results[$sql] = [];
        // add the result to the end of the array
        $this->results[$sql][] = $result; 
        // return its index
        return count($this->results[$sql]) - 1;
    }
}
诚然,这不是一个理想的解决方案,因为它需要修改代码以支持适配器对象,并删除一些功能(例如
mysql\u real\u escape\u string
),但它确实有效


如果您有更好的解决方案,请分享:-)谢谢

你能给我们看一些代码吗,比如连接是如何创建的,它是通过DI传递的吗?直接在使用它的类中实例化?它可以帮助我们。不确定DI是什么意思,但基本上有一个文件调用
mysql\u connect()
,其中包含凭证,然后在每个公共页面中导入。因此,当类加载到页面上时,mysql连接已经打开。我几乎设法用一种有趣的模仿方法解决了这个问题。如果有效的话,我会在明天把它作为一个答案发出去!。谢谢通过DI我谈论依赖注入,请展示你的代码,它比文字更有效地解释问题,并找到解决方案。向我们展示您要测试的函数/方法以及如何/在何处创建连接。好的,祝你好运。谢谢,我还是添加了代码:-)你能给我们看一些代码吗,比如如何创建连接,它是通过DI传递的吗?直接在使用它的类中实例化?它可以帮助我们。不确定DI是什么意思,但基本上有一个文件调用
mysql\u connect()
,其中包含凭证,然后在每个公共页面中导入。因此,当类加载到页面上时,mysql连接已经打开。我几乎设法用一种有趣的模仿方法解决了这个问题。如果有效的话,我会在明天把它作为一个答案发出去!。谢谢通过DI我谈论依赖注入,请展示你的代码,它比文字更有效地解释问题,并找到解决方案。向我们展示您要测试的函数/方法以及如何/在何处创建连接。好的,祝你好运。谢谢,我还是添加了代码:-)