1

別のメソッド(メソッド1と呼びましょう)を複数回呼び出すメソッド(メソッド2と呼びましょう)がありますが、引数は異なります。

クラス MyClass.php は次のとおりです。

<?php

class MyClass
{

    public function method1($arg)
    {
        return 'arg was ' . $arg;
    }

    public function method2()
    {
        // Calling the first time with 'one'
        $this->method1('one');

        // Calling other functions
        // ...

        // Calling the first time with 'two'
        $this->method1('two');
    }
}

テストするときは、method1 がいつどのように呼び出され、何を返すかを制御するために、method1 のスタブを作成します。method2 のテストでは、method2 内でコードが実行される順序に従います。

テスト クラス MyClassTest.php は次のとおりです。

<?php

require_once 'MyClass.php';

class MyClassTest extends PHPUnit_Framework_TestCase
{

    /** @test */
    public function method2_was_called_successfully_with_one_and_then_two()
    {
        $myClassMock = $this->getMockBuilder('MyClass')
                            ->setMethods(['method1'])
                            ->getMock();

        $myClassMock->expects($this->once())
                    ->method('method1')
                    ->with($this->stringContains('one', true))
                    ->will($this->returnValue('arg was one'));

        // Testing code for the code between the two calls
        // ...

        $myClassMock->expects($this->once())
                    ->method('method1')
                    ->with($this->stringContains('two', true))
                    ->will($this->returnValue('arg was two'));

        $myClassMock->method2();
    }
}

私のテストでは、PHPUnit がこの順序に従わず、method1 の最後の (この場合は 2 番目の) 呼び出しでスタックするように見えます。

1 件の失敗がありました:

1) MyClassTest::method2_was_called_successfully_with_one_and_then_two メソッド名の期待値が 1 回呼び出されたときと等しい 呼び出し MyClass::method1('one') のパラメータ 0 が期待値と一致しません。「1」に「2」が含まれていることをアサートできませんでした。

/path/to/the/files/MyClass.php:14 /path/to/the/files/MyClassTest.php:28

失敗!テスト: 1、アサーション: 0、失敗: 1。

ここで私が見逃している/間違っているという基本的なことについて何か考えはありますか?

4

1 に答える 1

2

モックを構成するときは、at()代わりに次を使用する必要があります。once()

    $myClassMock = $this->getMockBuilder('MyClass')
                        ->setMethods(['method1'])
                        ->getMock();

    $myClassMock->expects($this->at(0))
                ->method('method1')
                ->with($this->stringContains('one', true))
                ->will($this->returnValue('arg was one'));

    $myClassMock->expects($this->at(1))
                ->method('method1')
                ->with($this->stringContains('two', true))
                ->will($this->returnValue('arg was two'));


    // Testing code
    // ....
    // ....

余談ですが、いくつかのテストコードが既に実行された後にモックを構成するのは奇妙に見えます。通常のパターンは、モックがテストの開始時に受け取る必要があるすべての呼び出しを構成することです。次に、SUT を実行し、すべての呼び出しが行われたことを確認します (通常、この最後の手順は自動的に行われます)。

于 2015-01-19T08:56:27.690 に答える