[unit-testing] 추상 클래스 테스트

PHPUnit으로 추상 클래스의 구체적인 메소드를 어떻게 테스트합니까?

테스트의 일부로 일종의 객체를 만들어야한다고 기대합니다. 그래도, 이것에 대한 최선의 방법이나 PHPUnit이 이것을 허용하는지 모르겠습니다.



답변

추상 클래스의 단위 테스트는 인터페이스를 테스트하는 것을 의미하지 않습니다. 추상 클래스는 구체적인 메소드를 가질 수 있으며이 구체적인 메소드는 테스트 할 수 있습니다.

일부 라이브러리 코드를 작성할 때 응용 프로그램 계층에서 확장 할 것으로 예상되는 특정 기본 클래스를 갖는 것은 그리 드문 일이 아닙니다. 라이브러리 코드가 테스트되도록하려면 추상 클래스의 구체적인 메소드를 유추해야합니다.

개인적으로, PHPUnit을 사용하는데, 이런 종류의 것들을 테스트하는 데 도움이되는 스텁과 모의 객체가 있습니다.

직선에서 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());
    }
}

모의 객체는 몇 가지를 제공합니다.

  • 추상 클래스를 구체적으로 구현할 필요는 없으며 대신 스텁으로 벗어날 수 있습니다.
  • 구체적인 메소드를 호출하고 올바르게 수행한다고 주장 할 수 있습니다.
  • 구체적인 메소드가 구현되지 않은 (추상적 인) 메소드에 의존하는 경우 will () PHPUnit 메소드를 사용하여 리턴 값을 스텁 할 수 있습니다.

답변

그건 좋은 질문이야. 나도 이것을 찾고 있었다.
운 좋게도 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/PHPUnit


답변

PHP 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
}


답변

Eran, 당신의 방법은 작동해야하지만 실제 코드 전에 테스트를 작성하는 경향에 위배됩니다.

내가 제안하는 것은 문제의 추상 클래스의 비추 상 서브 클래스의 원하는 기능에 대한 테스트를 작성한 다음 추상 클래스와 구현 서브 클래스를 작성하고 마지막으로 테스트를 실행하는 것입니다.

테스트는 분명히 추상 클래스의 정의 된 메소드를 테스트해야하지만 항상 서브 클래스를 통해 수행해야합니다.


답변

넬슨의 대답이 잘못되었습니다.

추상 클래스는 모든 메소드가 추상 일 필요는 없습니다.

구현 된 메소드는 테스트해야합니다.

당신이 할 수있는 일은 단위 테스트 파일에 가짜 스텁 클래스를 만들고 추상 클래스를 확장하고 기능이 전혀 필요없는 것만 구현하고 테스트하는 것입니다.

건배.


답변

추상 클래스에서 이미 구현 된 메소드에 대해 단위 테스트를 수행하기 위해 추상 클래스를 서브 클래 싱하지 않으려는 경우 프레임 워크에서 추상 클래스 를 조롱 할 수 있는지 여부를 확인할 수 있습니다 .


답변