PHPUnitで抽象クラスの具象メソッドをテストするにはどうすればよいですか?
テストの一部として何らかのオブジェクトを作成する必要があると思います。ただし、これのベストプラクティスや、PHPUnitでこれが許可されているかどうかはわかりません。
PHPUnitで抽象クラスの具象メソッドをテストするにはどうすればよいですか?
テストの一部として何らかのオブジェクトを作成する必要があると思います。ただし、これのベストプラクティスや、PHPUnitでこれが許可されているかどうかはわかりません。
回答:
抽象クラスは具象メソッドを持つことができ、この具象メソッドをテストできるため、抽象クラスのユニットテストは必ずしもインターフェースのテストを意味しません。
一部のライブラリー・コードを作成するときに、アプリケーション層で拡張することが予想される特定の基本クラスがあることはそれほど珍しくありません。また、ライブラリコードが確実にテストされるようにするには、抽象クラスの具象メソッドをUTする手段が必要です。
個人的には、私はPHPUnitを使用しており、この種のテストに役立つように、いわゆるスタブとモックオブジェクトを用意しています。
abstract class AbstractClass
{
    public function concreteMethod()
    {
        return $this->abstractMethod();
    }
    public abstract function abstractMethod();
}
class AbstractClassTest extends PHPUnit_Framework_TestCase
{
    public function testConcreteMethod()
    {
        $stub = $this->getMockForAbstractClass('AbstractClass');
        $stub->expects($this->any())
             ->method('abstractMethod')
             ->will($this->returnValue(TRUE));
        $this->assertTrue($stub->concreteMethod());
    }
}モックオブジェクトはあなたにいくつかのものを与えます:
それは良い質問です。私もこれを探していました。
幸いなことに、PHPUnitにはすでにgetMockForAbstractClass()このケース用のメソッドがあります。たとえば、
protected function setUp()
{
    $stub = $this->getMockForAbstractClass('Some_Abstract_Class');
    $this->_object = $stub;
}これにはPHPUnit> 3.5.4が必要です。以前のバージョンにはバグがありました。
最新バージョンにアップグレードするには:
sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnitPHP 7以降、匿名クラスのサポートが追加されていることに注意してください。これにより、抽象クラスのテストをセットアップするための追加の手段が提供されます。これは、PHPUnit固有の機能に依存しないものです。
class AbstractClassTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var AbstractClass
     */
    private $testedClass;
    public function setUp()
    {
        $this->testedClass = new class extends AbstractClass {
            protected function abstractMethod()
            {
                // Put a barebones implementation here
            }
        };
    }
    // Put your tests here
}エラン、あなたの方法はうまくいくはずですが、実際のコードの前にテストを書く傾向に反します。
私が提案するのは、問題の抽象クラスの非抽象サブクラスの望ましい機能についてテストを記述し、次に抽象クラスと実装サブクラスの両方を記述して、最後にテストを実行することです。
テストでは、抽象クラスの定義済みメソッドをテストする必要がありますが、常にサブクラスを介してテストする必要があります。