mysqli
一連の関数を使用してデータベースにアクセスするさまざまなPHPスクリプトがあります。これらのスクリプトは、さまざまなエラー状態(mysqli_stmt_execute
falseを返すなど)を処理するために作成しました。
これらのエラー条件を偽造して、ユーザーが受信した出力がこれらの条件に適切であることを確認する簡単な方法はありますか?
例えば:
<?php
$mysqli = new mysqli("localhost", "user", "password", "db");
$query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
$stmt = $mysqli->prepare($query);
if (false === $stmt->execute()) {
echo "Oops! some_value for same_field in some_table returned false";
}
<?php
class my_mysqli extends mysqli
{
public function prepare ($query)
{
return new my_mysqli_stmt();
}
}
class my_mysqli_stmt extends mysqli_stmt {
public function execute ()
{
return false;
}
}
すべてのexecuteメソッドがfalseを返すように変更する必要があるのは、次のとおりです。
<?php
$mysqli = new my_mysqli("localhost", "user", "password", "db");
例えば:
<?php
$mysqli = mysqli_connect("localhost", "user", "password", "db");
$query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
$stmt = mysqli_prepare($mysqli, $query);
if (false === mysqli_stmt_execute($stmt)) {
echo "Oops! some_value for same_field in some_table returned false";
}
<?php
namespace my_faking_namespace {
function mysqli_stmt_execute($stmt)
{
return false;
}
$mysqli = mysqli_connect("localhost", "user", "password", "db");
$query = "INSERT INTO some_table (some_field) VALUES ('some_vale')";
$stmt = mysqli_prepare($mysqli, $query);
if (false === mysqli_stmt_execute($stmt)) {
echo "Oops! some_value for same_field in some_table returned false";
}
}
スクリプトはmy_faking_namespace\mysqli_stmt_execute()
、phpバージョンの代わりに呼び出します。
注:\mysqli_stmt_execute()
このバージョンがグローバル名前空間を明示的に呼び出すように関数を呼び出す場合、これは機能しません。
これらは、呼び出しスタックレベルで関数を変更し、カスタム拡張モジュールを使用して内部的にphpを変更します(インストールが必要です)。
override_function()
にはrename_function()
runkit_function_copy
、必要なものは何でも変更できます。runkit_function_redefine
runkit_function_remove
runkit_function_rename
nJoy!
自動化されたテストを探している場合、(PHPを使用して)実行する最良の方法はPHPUnitです。
PHPUnitを使用すると、ユーザーが受け取った出力がすべての異なる条件で適切であることを確認できる単体テスト(特にアサーション)を作成できます。
実稼働環境にいない場合、それを行う最良の方法は、PHPのさまざまなデータベースパラメータを変更することです。
間違った質問をしているのかもしれません。コアビジネスロジックがサードパーティのライブラリ/APIに依存しているのはなぜですか。いわゆるタマネギの建築について聞いたことがありますか?ドメイン、ビジネス、インフラストラクチャ/テストなど、これらのラインに沿ってアプリケーションをさらに階層化することで、変更されないもの、つまりビジネスロジックをテストする時間を大幅に短縮できます。
ただし、PHPは動的型付け言語であるため、モックは基本的に無料です。グローバル関数ではなくOO関数を使用している限り、テスト可能なコードを作成するために必要なのは、偽のデータベースハンドルをコードに挿入する方法だけです。$db
優れた方法は、関数/メソッドにパラメーターを追加することです。このような些細なこと:
function updateStuff($rowIds, $newValues, $db) { ... }
次に、カバーする単体テストでupdateStuff
、パラメータとしてモックオブジェクトを渡し$db
ます。