2016-12-29 11 views
1

特定の引数を指定してx回を呼び出すメソッドのテストに関する質問があります。PHPUnitテストメソッドは、特定の引数を指定しないで複数回呼び出されます。

状況:

私はクラスのグリッドを持っています。 2次元配列を扱います。このメソッドには、$ xと$ yの座標にvalue $ valueを設定するメソッドが含まれています。

次はクラスGridShifterがあります。それにはメソッドが含まれています

public function shiftRow($grid : Grid, $rowNumber : int) : void 

このメソッドは、行番号$ rowNumberのすべての値を右にシフトします。例えば:私はこれをあざけることにより、グリッドクラスのsetCellの機能をテストすることなくGridShifterのshiftRowメソッドをテストしたい

$grid = new Grid([[1, 2, 3]]); 
$gridShifter->shiftRow($grid, 1); 
// prints two dimensional array 
print_r($grid->printGrid()); 

[[3, 1, 2]] 

問題になりますメソッドが呼び出された回数(この例では3)をチェックし、呼び出しの引数をチェックします。私のために動作しませんでした

ソリューション:

私はいくつかのソリューションを試みました。 $ gridMockは、Gridクラスのモックです。

1)withConsecutiveまたは($ x)の

$gridMock->expect($this->exactly(3))->method('setCell')->withConsecutive(
    [1, 1, 3], 
    [1, 2, 2], 
    [1, 3, 1] 
); 

でこれは私のテストに合格したが、それはまたそれがで実行されます順序をテストするため、これは私のために動作しません。私が興味を持っていませんよそれらが呼び出される順序です。

2)これは私のニーズをテストするものではありません

$gridMock->expect($this->exactly(3))->method('setCell')->will($this-returnValueMap([ 
    [1, 1, 3], 
    [1, 2, 2], 
    [1, 3, 1] 
]); 

をreturnValueMap。 setCellは、他の引数

3でsetCellを起動せずに、引数1、1と3で3回呼び出されたときに、この場合のテストも合格します)logicalOr

$gridMock->expect($this->exactly(3))->method('setCell')->withConsecutive(
    $this->logicalOr(
     [1, 1, 3], 
     [1, 2, 2], 
     [1, 3, 1] 
    ) 
); 

とwithConsecutiveこれはあまりにも私のテストに合格解決策2と同じ問題があります。3つの引数すべてが呼び出されたかどうかはテストされません。

誰かが、setCellがshiftCellで3回呼び出されることをテストするソリューションを考えても、指定された異なる引数を順番どおりに渡すことはできますか?

上記のクラスと例は単純化されています。私の状況を説明していますが、それは私の正確な状況ではありません。すべての重要な詳細はこの質問にあります。事前に

おかげ

答えて

0

withCallbackは、ビルドのメソッドが動作しないときに移動するための方法です。期待される引数を配列に追加し、引数が配列内にあるかどうか(特定の順序で)コールバックチェックに追加します。もしそうなら、配列からそれらの引数を取り除きます(2回同じ引数がテストに失敗します)。いいえ - テストに失敗した場合

より複雑な引数 検証では、callback()制約を使用できます。この制約はPHPコールバックを唯一の 引数として受け取ります。 PHPのコールバックは、検証する引数を という唯一の引数として受け取り、引数が の検証に合格するとtrueを返し、そうでない場合はfalseを返します。 PHPUnitのマニュアルから

からTest doubles

0

あなたは、このために、コールバッククロージャを使用することができます。例:

$executions = []; 
$grid = $this->getMockBuilder('Grid')->getMock(); 
$grid->expects($this->any())->method('setCell')->will($this->returnCallback(
    function($x, $y, $value) use ($executions) { 
     $executions[] = func_get_args(); 
    } 
)); 

実行後、変数$実行には、メソッドの実行方法の完全なレコードが含まれます。それをトラバースして、必要な点を確認することができます。

関連する問題