〜real〜POST / GETデータに依存するPHPUnitテストを作成する方法は?

php phpunit testing
〜real〜POST / GETデータに依存するPHPUnitテストを作成する方法は?

開発者の作業を楽にするために、filter_input関数をエンベロープするPHPクラスを作成しました。 +「url」、「name」、「age」フィールドを持つHTMLフォームを検証するには、コードは次のようになります。

$post = Filter::POST();
if ($post->validate_string('name') && $post->validate_integer('age')) {
    $url = $post->sanitize_url('url');
}

次と同じです:

if (filter_input(INPUT_POST,'name',FILTER_UNSAFE_RAW) && filter_input(INPUT_POST,'age',FILTER_VALIDATE_INTEGER)) {
    $url = filter_input(INPUT_POST,'url',FILTER_SANITIZE_URL);
}

さて、コードは完成したと思うので、今度はそのためのPHPUnitテストを作成したいと思います。

問題は、この場合ではなく、PHPUnitメソッドでGET / POSTデータを偽装する方法がわからないことです。 + $ _POST`に値を挿入する必要はありません。実際の $ _POST`スーパーグローバルではなく、 `filter_input`がスクリプトが受信したデータで機能するため、「実際の」データが必要です。

次のPHPTテストとPHPUnitメソッドを使用してこれを達成しようとしましたが、まったく成功しませんでした。

--TEST--
Generates POST and GET data to be used in FilterTest.php
--POST--
name=Igor&age=20
--GET--
name=Igor&age=19
--FILE--

--EXPECT--
Igor = 20

” ” ‘

public function testPhpt() {
 $phpt = new PHPUnit_Extensions_PhptTestCase('FilterTest_data.phpt', array('cgi' => 'php-cgi'));
 $result = $phpt->run();
 $this->assertTrue($result->wasSuccessful());
}

EDIT

元のコード:http://pastebin.com/fpw2fpxM + 初期テストに使用されるコード:http://pastebin.com/vzxsBQWm +しかし、それは私が働く場所で物事がどのように機能するかです。 本当に必要だと思われる場合は、コードを翻訳できます)。

このクラスをテストするために何ができますか?

  7  1


ベストアンサー

生のPOSTデータを偽造することはできません。 しかし、問題はあなたのコードにあります:それはユニットテスト可能ではありません。 の代わりに:

if (filter_input(INPUT_POST,'name',FILTER_UNSAFE_RAW) && filter_input(INPUT_POST,'age', FILTER_VALIDATE_INTEGER)) {
    $url = filter_input(INPUT_POST,'url',FILTER_SANITIZE_URL);
}

あなたが持っていた場合:

if (filter_var($data['name'], FILTER_UNSAFE_RAW) && filter_var($data['age'], FILTER_VALIDATE_INT)) {
    $url = filter_var($data['url'], FILTER_SANITIZE_URL);
}
// where $data is a copy of $_POST in that case

コードユニットをテスト可能にし、以前のコードと同様に_同じこと_になります。

追伸:FILTER_VALIDATE_INTEGERは無効です。 このための適切な定数はFILTER_VALIDATE_INTです

2


あなたのコードには2つの問題があります。 1つは、テストするのが難しいグローバル変数にアクセスしていることです。 2番目は、クラスを特定のデータ(post、getなど)に緊密にバインドしていることです。

あなたがすべきことは、クラスがこの種のインターフェースを満たすようにすることです:

$filter = new Filter($_POST);
$filter->validate_string('name');

その利点は明らかです。 入力として $ _POST`や $ _GET`やその他の事前定義された型を使用する必要はありません。 (コンストラクタに渡すだけなので)任意のソースからの入力を検証できるだけでなく、さらに重要なこととして、テストのために任意のデータをそこに挿入できます。

おっと、「filter_input」の使用に関する部分を見逃しました。 解決策は、代わりに `filter_var`を使用することです。 任意の変数でフィルターを実行できます。

2


タイトルとURLをコピーしました