6

これは、PHPUnitで無駄にした時間を他の誰かを救おうとするほどの問題ではありません。

私の問題は、依存テストで使用したときに、モックオブジェクトが期待値を返さないことでした。PHPUnitは、構文によってそのように見えても、依存するテスト間で同じオブジェクトを保持しないようです。

PHPUnitがこれを行う理由を誰かが知っていますか?これはバグですか?PHPUnitでのこのようなものは、使用するのを非常に苛立たせます。

<?php 
class PhpUnitTest
extends PHPUnit_Framework_TestCase
{
private $mock;

public function setUp()
{
    $this->mock = $this->getMock('stdClass', array('getFoo'));

    $this->mock->expects( $this->any() )
        ->method('getFoo')
        ->will( $this->returnValue( 'foo' ) );
}

public function testMockReturnValueTwice()
{
    $this->assertEquals('foo', $this->mock->getFoo());
    $this->assertEquals('foo', $this->mock->getFoo());

    return $this->mock;
}

/**
 * @depends testMockReturnValueTwice
 */
public function testMockReturnValueInDependentTest($mock)
{
    /* I would expect this next line to work, but it doesn't! */
    //$this->assertEquals('foo', $mock->getFoo());

    /* Instead, the $mock parameter is not the same object as
     * generated by the previous test! */
    $this->assertNull( $mock->getFoo() );
}

}
4

2 に答える 2

5

PHPUnitのモックオブジェクトは、それらが作成されたテストインスタンスにアタッチされます。これは、定義上、単一のテストメソッドを意味します。これは、PHPUnitを使用すると、テスト中に満たす必要のあるモックの期待値を指定できるためです。これを行うために、メソッドが正常に終了すると、それらの期待を表明します。モックが複数のテストにまたがって生きていた場合、期待は機能しません。

問題は、これがスタブオブジェクトをサポートしていないことです。メソッドと入力に応答して実行される固定アクションのみを含むモックです。スタブは、それらのメソッドがフルモックのように呼び出されることを検証しません。setUpBeforeClass()おそらく、PHPUnitは、テストインスタンスに関連付けられていないスタブを作成する機能の恩恵を受ける可能性があります。

もう1つのオプションは、 MockeryPhakeなどの外部モックオブジェクトライブラリを使用することです。

編集:サンプルコードをもう一度調べた後、なぜこの動作に驚かされるのだろうか。Shaunakが書いたように、setUp()各テストメソッドが実行される前に新しいインスタンスで呼び出されます。したがって、各インスタンスは新しいモックを受け取りますstdClass。期待値を受け取るテストメソッドを1つだけにしたい場合は、それをテストメソッド自体の中に追加します。setUp()すべてのテストメソッドに共通する動作を使用して、モックオブジェクトを作成できます。

于 2011-07-26T07:38:01.007 に答える
2

私はPHPの人ではないので、間違っている場合は訂正してください。ただし、すべての単体テストは次の順序で実行されるように設計されています。

セットアップ->テスト機能->破棄。

そのため、テスト関数を実行する前に、セットアップと破棄の関数が毎回呼び出されます。これは、単体テストの目的を維持するために意図的に行われます。

依存する単体テストケースが必要な場合は、グローバル変数に依存するのではなく、そのようにコーディングする必要があります(これにより、単体テストの目的が損なわれます!)。ある関数に依存するテストケース「A」がある場合は、「A」からその関数を呼び出してから、値をアサートします。

于 2011-07-25T20:50:10.647 に答える