ファイルシステムの相互作用の単体テストのために vfsStream を試していますが、すぐに大きなハードルにぶつかりました。テスト対象のコードが行う検証チェックの 1 つは、提供された入力パスに対して realpath() を実行して、それが実際のパスであり、ナンセンスではないことをテストすることです。ただし、realpath は vfsstream パスでは常に失敗します。
次のコードは、特定のクラス以外の問題を示しています。
$content = "It rubs the lotion on its skin or else it gets the hose again";
$url = vfsStream::url ('test/text.txt');
file_put_contents ($url, $content);
var_dump ($url);
var_dump (realpath ($url));
var_dump (file_get_contents ($url));
出力は次のとおりです。
string(27) "vfs://FileClassMap/text.txt"
bool(false)
string(61) "It rubs the lotion on its skin or else it gets the hose again"
明らかに、vfsStream がファイルを作成し、指定されたコンテンツを書き込みましたが、そのパスが realpath で正しいことを確認できません。realpath は実際のコード内で使用されているため、これに対処する方法が必要です。
コード内で重要な機能を実行するため、realpath を削除することは賢明なアプローチではないと思います。コードをテスト可能にするためだけに重要なチェックを削除するのは、かなり貧弱な解決策のようです。テスト目的で無効にできるように、テストの周りに if を配置することもできますが、これも良い考えではないと思います。また、realpath () を呼び出す可能性のあるコード内のすべてのポイントでそれを行う必要はありません。3 番目のオプションは、ファイル システムの単体テスト用に RAM ディスクをセットアップすることですが、これも理想的ではありません。自分でクリーンアップする必要があり (これは vfsstream がその必要性を回避するのに役立つはずです)、実際にそれを行う方法は OS ごとに異なるため、単体テストは OS に依存しなくなります。
実際にリアルパスで動作する形式で vfsstream パスを取得する方法はありますか?
完全を期すために、以下は実際にテストしようとしているクラスのコード フラグメントです。
if (($fullPath = realpath ($unvalidatedPath))
&& (is_file ($fullPath))
&& (is_writable ($fullPath))) {
次のリファクタリング (考えられる解決策 2 による) により、vfsStream でテストできますが、本番環境では問題になる可能性があると思います。
// If we can get a canonical path then do so (realpath can fail on URLs, stream wrappers, etc)
$fullPath = realpath ($unvalidatedPath);
if (false === $fullPath) {
$fullPath = $unvalidatedPath;
}
if ((is_file ($fullPath))
&& (is_writable ($fullPath))) {