9

私はクラスの単体テストを作成していますが、単体テストFooはかなり新しいです。

私のクラスの重要なコンポーネントは、そのインスタンスにいくつかのオブジェクトBarCollectionが含まれていることです。Barの1つのメソッドはコレクションを反復処理し、コレクション内の各オブジェクトに対してFooいくつかのメソッドを呼び出します。Barスタブオブジェクトを使用して、テストクラスの一連の応答を生成したいと思います。Bar反復するときにスタブクラスが異なる値を返すようにするにはどうすればよいですか?私はこれらの線に沿って何かをしようとしています:

$stubs = array();
foreach ($array as $value) {
    $barStub = $this->getMock('Bar');
    $barStub->expects($this->any())
            ->method('GetValue')
            ->will($this->returnValue($value));
    $stubs[] = $barStub;
}
// populate stubs into `Foo`

// assert results from `Foo->someMethod()`

したがってFoo->someMethod()、オブジェクトから受け取った結果に基づいてデータを生成しBarます。ただし、配列が1より大きい場合は常に、次のエラーが発生します。

There was 1 failure:

1) testMyTest(FooTest) with data set #2 (array(0.5, 0.5))
Expectation failed for method name is equal to <string:GetValue> when invoked zero or more times.
Mocked method does not exist.
/usr/share/php/PHPUnit/Framework/MockObject/Mock.php(193) : eval()'d code:25

私が持っていた考えの1つは、コールバックメソッドを呼び出すために使用することでしたが、どのオブジェクトが呼び出しを行っているか(したがって、どのような応答を返すか)を->will($this->returnCallback())コールバックに示す方法がわかりません。Bar

もう1つのアイデアは、onConsecutiveCalls()メソッドなどを使用して、スタブに1回目、2回目などを返すように指示することですが、これを行う方法が正確にはわかりません。また、クラスがコレクションに対して順序付けられた反復以外のことを行った場合、それをテストする方法がないことも心配しています。

4

3 に答える 3

2

残念ながら、getMock()を使用して実際の質問を解決できるかどうかはわかりませんが、 getMock()自体の経験はわずかです。

私が手に負えないと考えることができるのは、Barクラスがわからない場合だけですが、これは役に立たない可能性があります。getMock()の3番目のパラメーターを使用すると、コンストラクター引数を(配列として)渡すことができます。

Barをテストヘルパーとして拡張する独自のモッククラスを作成します(「テストでのみ使用される別のクラス」のファンシーな名前)。これは、私が好きなことを正確に実行し、一連のクラスをFooオブジェクトに挿入します。getMock()では実行されない問題のメソッドを完全に置き換えることができるため、必要なすべての制御が可能になります。もちろん、これは、このテストでBarクラスをテストしていないことも意味します。これは、テストしたクラスごとに個別のテストクラスを作成することをお勧めしますが、それが不必要に純粋である場合もあります。

$stubs = array();
foreach ($array as $value) {
    $stubs[] = new MyBarTestHelper($value);
}

それはさておき、複数の配列要素がある場合にのみ説明されている例外が表示されていることに正直驚いています。PHPUnitは、実際には、追跡できるようにするメソッドをgetMock()パラメーターとして宣言することを期待しており、それ以外の場合は、本質的に内部で行うことはクラスの独自の拡張を作成することであるため、エラーが発生します。明示的に宣言した各メソッドを、呼び出されたかどうかを判別できるロジックでラップします(=メソッド名を論理リストに追加します)。

だから私を素朴に着色してください(真剣に、私はおそらく、私はテスト初心者です)が、これがあなたに役立つかどうかを確認してください:

$stubs = array();
foreach ($array as $value) {
    $barStub = $this->getMock('Bar', array('GetValue'));
    $barStub->expects($this->any())
            ->method('GetValue')
            ->will($this->returnValue($value));
    $stubs[] = $barStub;
}
于 2010-03-29T09:31:03.987 に答える
0

これは、グローバルの使用に慣れている場合に呼び出される一連の値を順番に返すという要件を満たす必要があります。どのバーが呼び出されるかはわかりませんが、各バーがFooによって順番に1回呼び出される場合は、テストデータを入力するのはそれほど難しくありません。

$barTestData = array('empty',1,2,3,4,5,6);

function barDataCallback(){
    global $barTestData;
    return next($barTestData);
}
于 2010-03-25T19:18:59.893 に答える
0

コードの「->method('GetValue')」の後に余分な括弧があることに気づきました。それをコピーして貼り付けたかどうかはわかりません。

于 2010-03-26T23:17:37.010 に答える