PHP 5.3.10、PHPUnit 3.6.10
オブジェクトからメソッドを使用できるように、オブジェクトの初期化に失敗するテストでコードを呼び出しています。問題は、これがレガシーコードであり、この関数がアプリケーションで常に使用されていることです。PHPでネイティブに動作しますが、PHPUnit内から実行した場合は動作しません。呼び出しは、アプリケーション用に持っているPHP拡張機能にアクセスします。この問題を示す非常に簡単な例を以下に示します。
PHP拡張機能(FOO)への呼び出しをラップするクラスファイル:
class FOO
{
$private $Bar;
pubilc function __construct()
{
$this->Bar = new OurPHPExtensionObject();
}
public function Option1($Variable)
{
return $this->Bar->OurPHPExtensionMethod($Variable);
}
public function _Option1($Variable)
{
return $Variable; // Dummy to test that code is loaded
}
}
$Bar = new FOO();
これにより、オブジェクトが作成され、初期データが読み込まれるため、1回だけ実行されます。これを使用する他の呼び出しには、このクラスを含むファイルが含まれます。アプリケーションが実行を継続すると、最初に初期化のみが実行され、次にglobalキーワードを使用してこのオブジェクトを参照し、そのメソッドにアクセスします。
Function.phpの例:
require_once('FOO.class');
function CausesError($Parameter)
{
global $Bar; // Using $Bar defined from FOO.class
$ErrorCreated = $Bar->Option1($Parameter); // Call Option from Class
}
次に、個々のプログラムは、require_once()を使用してFunction.phpファイルを含めるだけで、どこからでもロードされるファイルのインスタンスが1つだけになるようにします。
サンプルファイル:
require_once('Function.php');
echo CausesError('Variable Text') . "\n";
これにより、エラーが発生します。
Fatal error: Call to a member function Option1() on a non-object in ...
PHPUnitを初めて使用し、テストを実行できるようになるまで既存のコードへの変更を最小限に抑えようとしているので、これを処理する方法についていくつかの提案が必要です。大量の既存のコードは、Function.phpをインクルードし、関数(CausesError)を呼び出すだけで、この関数を呼び出しています。これを取得してデータを返す方法がわかりません。
私のテストファイルには、各テストの前にsetUp()メソッドがあります。
class TEST_Function extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
require_once('Function.php);
echo _Option1('Sample') . "\n"; // Works and ECHOs to show code loaded
echo Option1('Sample2') . "\n"; // Fails with the error
}
public function testFunctionOption1()
{
$this->assertEquals(Option1('English'), 'English'); // Error
}
}
テストで関数をモックする必要がありますか?この関数はコード全体で使用されているため、どのテストにこれが含まれるかわかりません。
これが環境とコードレイアウトを説明していることを願っています。よろしくお願いします。