パラメーターに基づいて異なる値を返すようにPHPUnit MockObjectsを取得するにはどうすればよいですか?
-
07-07-2019 - |
質問
引数に関係なく 'return value'
を返すPHPUnitモックオブジェクトがあります:
// From inside a test...
$mock = $this->getMock('myObject', 'methodToMock');
$mock->expects($this->any))
->method('methodToMock')
->will($this->returnValue('return value'));
できることは、モックメソッドに渡された引数に基づいて異なる値を返すことです。私は次のようなものを試しました:
$mock = $this->getMock('myObject', 'methodToMock');
// methodToMock('one')
$mock->expects($this->any))
->method('methodToMock')
->with($this->equalTo('one'))
->will($this->returnValue('method called with argument "one"'));
// methodToMock('two')
$mock->expects($this->any))
->method('methodToMock')
->with($this->equalTo('two'))
->will($this->returnValue('method called with argument "two"'));
しかし、これにより、引数が 'two'
でモックが呼び出されない場合、PHPUnitからエラーが発生するため、 methodToMock( 'two')
の定義最初の定義を上書きします。
だから私の質問は:引数に基づいて異なる値を返すPHPUnitモックオブジェクトを取得する方法はありますか?もしそうなら、どのように?
解決
コールバックを使用します。例えば(PHPUnitのドキュメントから直接):
<?php
class StubTest extends PHPUnit_Framework_TestCase
{
public function testReturnCallbackStub()
{
$stub = $this->getMock(
'SomeClass', array('doSomething')
);
$stub->expects($this->any())
->method('doSomething')
->will($this->returnCallback('callback'));
// $stub->doSomething() returns callback(...)
}
}
function callback() {
$args = func_get_args();
// ...
}
?>
callback()で必要な処理を行い、必要に応じて$ argsに基づいて結果を返します。
他のヒント
最新のphpUnitドキュメントから:&quot;場合によっては、スタブメソッドは、事前定義された引数のリストに応じて異なる値を返す必要があります。 returnValueMap()<を使用できます。 / a>引数を対応する戻り値に関連付けるマップを作成します。&quot;
$mock->expects($this->any())
->method('getConfigValue')
->will(
$this->returnValueMap(
array(
array('firstparam', 'secondparam', 'retval'),
array('modes', 'foo', array('Array', 'of', 'modes'))
)
)
);
同様の問題がありました(わずかに異なりますが、引数に基づいて異なる戻り値を必要としませんでしたが、2つの引数セットが同じ関数に渡されることを確認する必要がありました)。私はこのようなものを使用してつまずいた:
$mock = $this->getMock();
$mock->expects($this->at(0))
->method('foo')
->with(...)
->will($this->returnValue(...));
$mock->expects($this->at(1))
->method('foo')
->with(...)
->will($this->returnValue(...));
これは完全ではありません。foo()の2つの呼び出しの順序がわかっている必要があるためですが、実際にはこれはおそらく to 悪くありません。
おそらく、OOP形式でコールバックを行いたいでしょう:
<?php
class StubTest extends PHPUnit_Framework_TestCase
{
public function testReturnAction()
{
$object = $this->getMock('class_name', array('method_to_mock'));
$object->expects($this->any())
->method('method_to_mock')
->will($this->returnCallback(array($this, 'returnCallback'));
$object->returnAction('param1');
// assert what param1 should return here
$object->returnAction('param2');
// assert what param2 should return here
}
public function returnCallback()
{
$args = func_get_args();
// process $args[0] here and return the data you want to mock
return 'The parameter was ' . $args[0];
}
}
?>
それはあなたが尋ねるとおりのものではありませんが、場合によっては役立ちます:
$mock->expects( $this->any() ) )
->method( 'methodToMock' )
->will( $this->onConsecutiveCalls( 'one', 'two' ) );
onConsecutiveCalls -指定された順序で値のリストを返します
2レベルの配列を渡します。各要素は次の配列です:
- 最初はメソッドのパラメーターであり、最小は戻り値です。
例:
->willReturnMap([
['firstArg', 'secondArg', 'returnValue']
])
次のように引数を返すこともできます:
$stub = $this->getMock(
'SomeClass', array('doSomething')
);
$stub->expects($this->any())
->method('doSomething')
->will($this->returnArgument(0));
モッキングドキュメントでわかるように、メソッド returnValue($ index)
は、指定された引数を返すことができます。
このような意味ですか?
public function TestSomeCondition($condition){
$mockObj = $this->getMockObject();
$mockObj->setReturnValue('yourMethod',$condition);
}
同様の問題がありましたが、同様に解決できませんでした(PHPUnitに関する情報は驚くほど少ないです)。私の場合、各テストを別々のテスト(既知の入力と既知の出力)にしました。私は、万能のモックオブジェクトを作成する必要はなく、特定のテスト用に特定のオブジェクトのみが必要であることに気付きました。単位。これがあなたに当てはまるかどうかはわかりませんが、それはテストする必要があるものです。
$this->BusinessMock = $this->createMock('AppBundle\Entity\Business');
public function testBusiness()
{
/*
onConcecutiveCalls : Whether you want that the Stub returns differents values when it will be called .
*/
$this->BusinessMock ->method('getEmployees')
->will($this->onConsecutiveCalls(
$this->returnArgument(0),
$this->returnValue('employee')
)
);
// first call
$this->assertInstanceOf( //$this->returnArgument(0),
'argument',
$this->BusinessMock->getEmployees()
);
// second call
$this->assertEquals('employee',$this->BusinessMock->getEmployees())
//$this->returnValue('employee'),
}
試してください:
->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));