4

依存関係を、たとえばコンテキスト テスト スイートを介して派生したクラスに注入することが可能かどうか疑問に思っていPHPUnit_Framework_TestCaseました。PHPUnit が、phpunit.xml構成ファイルなどを使用して手動で呼び出されたかどうかに関係なく処理できるようにするにはどうすればよいでしょうか。

次の例を検討してください。

<?php
interface AnyGreeter {   
    public function greet($recipient);
}   

class FriendlyGreeter implements AnyGreeter {   
    public function greet($recipient) {   
        return "Hello {$recipient}!";
    }   
}   

class DorkGreeter implements AnyGreeter {
    public function greet($recipient) {   
        return "Get lost, {$recipient}!";
    }   
}

ここで、クラスを実装するための一般的なテストをいくつか提供したいと思いますAnyGreeter

<?php
class GeeterTest extends PHPUnit_Framework_TestCase {

    public function testGreet() {   
        $greeter = $this->getGreeter();
        $message = $greeter->greet("world");
        $this->assertContains("world", $message);
    }   

    public function setGreeter(AnyGreeter $greeter) {   
        $this->greeter = $greeter;
    }   

    public function getGreeter() {   
        if (null === $this->greeter) {
            $this->markTestSkipped("No greeter provided");
        }   
        return $this->greeter;
    }

    private $greeter;
} 

これは、私自身の実装だけでなく、将来の実装 (私が制御していない) でも再利用される可能性があります。

特にインターフェースに大きく依存しているプロジェクトでは、これはどのように可能ですか? 抽象的なテストを書いて、実装ごとに拡張したくはありません -

ありがとう!

4

2 に答える 2

1

グレンが述べたように、あなたの最善のアプローチはプロバイダーを使用すると思います。

class GreeterTestCase extends PHPUnit_Framework_TestCase
{
    protected function getGreeter()
    {   
    }   

    /** 
     * @dataProvider providerGreeter
     */
    public function testGreet(AnyGreeter $greeter)
    {   
        $message = $greeter->greet('world');
        $this->assertType('string', $message, 'AnyGreeter::greet() must return string');
        $this->assertContains('world', $message);
    }   

    public function providerGreeter()
    {   
        return array(array($this->getGreeter()));
    }   
}

このようにして、ライブラリの他の部分がこのテストケースを拡張して、独自の実装が基本的なインターフェイス仕様を満たしているかどうかをテストできます。その実装に固有のカスタム単体テストはすべて、拡張テストケースに含まれます。

これで、単一の実装をテストするか(独自の単体テストがある場合があります)、実装の負荷をグループ化してデフォルトのテストを取得するかを選択できます。

class AnyGreeterTestCase extends GreeterTestCase
{
    public function providerGreeter()
    {
        return array(
            array(new FriendlyGreeter()),
            array(new DorkGreeter()),
        );
    }
}
于 2012-06-01T11:21:42.797 に答える
1

私はこれが行われたのを見たことがなく、ドキュメントには何もありません。テストには少し複雑なようです。データプロバイダーを使用してグリーターオブジェクトを testGreeter メソッドに渡すことで問題を解決できます。その後、プロバイダーで具体的なグリータークラスの配列を維持するだけです。

ここの「データプロバイダー」セクションを参照してください: http://www.phpunit.de/manual/3.2/en/writing-tests-for-phpunit.html

于 2012-05-31T19:35:22.963 に答える