2017-11-07 1 views
1

こんにちは、PHPUnitの4.8モックMySQLデータベースインタフェース

私は古いmysqlライブラリー(例えばmysql_query($sql))を使用するレガシーコードの束を持っているし、PHPUnitのでそれをテストしようとしています(4.8を実行すること最新のものですさまざまな理由からサーバー上で)。

誰かがこのデータベース接続を模擬して、あらかじめ決められたクエリを実行したときに所定の結果を返す方法を知っていますか?私はgetConnection()を使用してみました(ここでは、ドキュメントごとに:http://devdocs.io/phpunit~4/database)無駄に。例えば

私はこのクラスを持っている:

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_connect()コールはファイル内で行われているが、それは、クラスファイル自体に必要とされていないことをすべてのページにロードされているdb.phpと呼ばれる。)

ありがとうございます。

+0

あなたは私たちにいくつかのコードを表示できますか?どのように接続が作成されたか、それはDIによって渡されますか?それを使用するクラスに直接インスタンス化されていますか?それは私たちを助けるかもしれません。 – olibiaz

+0

あなたはDIが何を意味するのかはっきりしていませんが、基本的には、すべての公開ページにインポートされる資格情報とともにmysql_connect()を呼び出すファイルがあります。したがって、クラスがページにロードされると、mysql接続はすでに開かれています。私は面白いMockingメソッドでそれを回避することがほとんどできました。それがうまくいくなら、私はそれをtommorow :-)!と答えて投稿します!ありがとう! –

+0

私は依存性注入について話しています。問題を説明する言葉よりも効率的なコードを表示し、解決策を見つけました。テストする関数/メソッドと、接続がどのように/どこに作成されたかを表示します。あなたの試しに大丈夫です。 – olibiaz

答えて

0

このような状況に悩まされている人は、機能的なAPIのフォールバックを含むPDOのモックを構築することで、Testable 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_real_escape_stringなど)いくつかの機能を除去するように、これは理想的なソリューションではないが、それは働いた....

もっと良い解決策をお持ちでしたら、お気軽にご連絡ください:-)ありがとうございます!

関連する問題