154

'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"'));

しかし、これにより、モックが引数 で呼び出されないと PHPUnit が文句を言うので、 の定義が最初の の定義を上書きする'two'と仮定します。methodToMock('two')

だから私の質問は: PHPUnit モック オブジェクトを取得して、その引数に基づいて異なる値を返す方法はありますか? もしそうなら、どのように?

4

11 に答える 11

134

コールバックを使用します。例(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に基づいて結果を返します。

于 2008-11-15T11:13:17.827 に答える
125

最新のphpUnitドキュメントから:「スタブメソッドは、事前定義された引数のリストに応じて異なる値を返す場合があります。returnValueMap()を使用して、引数を対応する戻り値に関連付けるマップを作成できます。」

$mock->expects($this->any())
    ->method('getConfigValue')
    ->will(
        $this->returnValueMap(
            array(
                array('firstparam', 'secondparam', 'retval'),
                array('modes', 'foo', array('Array', 'of', 'modes'))
            )
        )
    );
于 2012-07-31T09:27:47.723 に答える
54

同様の問題がありました(わずかに異なりますが...引数に基づいて異なる戻り値は必要ありませんでしたが、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 回の呼び出しの順序がわかっている必要があるため、完全ではありませんが、実際には、これはおそらくそれほど悪くはありません。

于 2010-01-13T08:53:34.943 に答える
30

おそらく、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, 'returnTestDataCallback')));

        $object->returnAction('param1');
        // assert what param1 should return here

        $object->returnAction('param2');
        // assert what param2 should return here
    }
    
    public function returnTestDataCallback()
    {
        $args = func_get_args();

        // process $args[0] here and return the data you want to mock
        return 'The parameter was ' . $args[0];
    }
}
?>
于 2011-01-12T00:01:45.323 に答える
21

それはまさにあなたが尋ねるものではありませんが、場合によっては役立つことがあります:

$mock->expects( $this->any() ) )
 ->method( 'methodToMock' )
 ->will( $this->onConsecutiveCalls( 'one', 'two' ) );

onConsecutiveCalls - 指定された順序で値のリストを返します

于 2014-03-19T10:51:41.010 に答える
3

次のように引数を返すこともできます。

$stub = $this->getMock(
  'SomeClass', array('doSomething')
);

$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->returnArgument(0));

Mocking documentationでわかるように、メソッドreturnValue($index)は指定された引数を返すことができます。

于 2013-08-06T08:59:43.217 に答える
0

私も同様の問題を解決できませんでした(PHPUnitに関する情報は驚くほど少ないです)。私の場合、各テストを別々のテスト(既知の入力と既知の出力)にしただけです。何でも屋のモックオブジェクトを作成する必要はなく、特定のテストに特定のオブジェクトを作成するだけでよいことに気付きました。そのため、テストを分離して、コードの個々の側面を個別にテストできます。単位。これがあなたに当てはまるかどうかはわかりませんが、それはあなたがテストする必要があるもの次第です。

于 2008-11-10T15:13:04.950 に答える
0

このようなことを意味しますか?

public function TestSomeCondition($condition){
  $mockObj = $this->getMockObject();
  $mockObj->setReturnValue('yourMethod',$condition);
}
于 2008-11-10T14:25:19.337 に答える
-2

試す :

->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));
于 2009-10-03T21:26:30.617 に答える