2

私はシステムをPHPUnitとより互換性のあるものにすることに取り組んでいるので、クラスの単体テストをさらに行うことができ、それらのいくつかをモックオブジェクトで動作させることができましたが、私には思えない問題に遭遇しました回避する。

私たちが持っているクラスの1つ(私はモックバージョンを作成しています)はクエリ用です。クエリ文字列を「query()」メソッドに渡すと、クエリがログに記録され、実行されて結果が返されます。また、mysql_fetch_assocを「get_row()」と呼ばれるメソッドでラップします。このメソッドは、元の値とよく似た配列値を返します。

問題は、一部のメソッドでは、「query()」メソッドに複数のクエリが渡されるため、データをさまざまな変数にロードするために複数のwhileループを実行する必要があることです。以下に簡略化したバージョンを作成しました。

class object{
    public function __construct($query){
        $this->query = $query;
    }

    public function loadData(){

        $data1 = queryDataSource("SELECT * FROM data1");
        $data2 = queryDataSource("SELECT * FROM data2");

        return Array(
            "data1" => $data1,
            "data2" => $data2,
        );

    }

    private function queryDataSource($query){
        $this->query->query($query)

        while($row = $this->query->get_row()){
            $result[] = $row;
        }

        return $result
    }
}

class testObject extends PHPUnit_Framework_TestCase{
    method testLoadData(){
        $test_data = Array('name' => 'Bob', 'number' => '98210');

        $query = $this->getMock('Query');
        $query->expects($this->any())->method('query');
        $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data);
        $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False);
        $query->expects($this->at(3))->method('get_row')->will($this->returnValue($test_data);
        $query->expects($this->at(4))->method('get_row')->will($this->returnValue(False);
    }
}

$ object-> queryDataSource()の最初のwhileループをエスケープするために、mysql_fetch_assocを実行するときに発生するように、ブール値のFALSE値を返します。問題は、2番目のクエリを実行してget_row()を介してデータをフェッチしようとすると、モックオブジェクトがat(3)ポイントに移動するよりもFALSEratehrを返し続けるように見えることです。これは4つのオブジェクトでも発生し、最初のオブジェクトのみが戻り値としてテストデータを取得し、2回目はFALSEを取得し、他のオブジェクトは毎回FALSEを取得します。

これを回避する方法があるかどうか誰かが知っていますか?FALSEフラグを削除し、at()に奇数の値を設定しようとしましたが、同じ問題が発生し、at(1-2)のデータを返すように試行しましたが、すべてのデータがに渡されました。最初のwhileループで、他には何もありません。

あなたが与えることができるどんな助けにも感謝します、問題の説明が十分に明確であることを望みます

4

2 に答える 2

7

疑似コードのように見えるのでコードを実行できませんが、私が理解したことから、あなたは次のようにモックしようとしているということです。

Call to query, get_row, get_row, query, get_row, get_row.

あなたが遭遇したと思われる問題は->at()マッチャーの数が1つごとではmethodなく1つごとobjectにカウントされることです。

したがって、おそらく書きたいのは次のとおりです。

    $query->expects($this->any())->method('query');
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data);
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False);
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data);
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False);

または、読みやすくするために、次のようにします。

    $query->expects($this->at(0))->method('query');
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data);
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False);
    $query->expects($this->at(3))->method('query');
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data);
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False);

モックを使用すると、「クエリ」への2回目の呼び出しで1回の「呼び出し」がカウントされ、2回目の呼び出しがスキップされるという問題が発生しましたreturn($test_data);

于 2012-10-03T14:30:48.723 に答える
1

残念ながら、at()テストは実装に非常に強くバインドされます。

テストされたメソッド内で2つのメソッド呼び出しを再配置した場合、機能はまったく同じですが、使用するすべてのテストat()が失敗し、多くの場合、次のような不可解なメッセージが表示されると想像してください。method doesn't exist at index N

「これは正確にこのように呼ばれ、次にこれは正確にこのように呼ばれる」と具体的に言いたい場合は素晴らしいですが、アサーションが必要な場合は、PHPUnitモック拡張機能の1つ、特にMockeryとここのガイド(タッチ時代遅れだと思います)

他にもあります。

于 2012-10-23T19:52:28.380 に答える