Тестирование Абстрактных Классов
Как проверить конкретные методы абстрактного класса с помощью PHPUnit?
Я ожидал бы, что мне придется создать какой-то объект в рамках теста. Хотя, я понятия не имею, лучшая практика для этого или если PHPUnit позволяет это.
6 ответов:
модульное тестирование абстрактных классов не обязательно означает тестирование интерфейса, так как абстрактные классы могут иметь конкретные методы, и эти конкретные методы могут быть протестированы.
это не так уж редко, при написании некоторого кода библиотеки, чтобы иметь определенный базовый класс, который вы ожидаете расширить в вашем прикладном уровне. И если вы хотите убедиться, что код библиотеки проверен, вам нужны средства для использования конкретных методов абстрактных классов.
лично я использую 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()); } }
макет объекта дает вам несколько вещей:
- вы не обязаны иметь конкретную реализацию абстрактного класса, и может уйти с заглушкой вместо
- вы можете вызвать конкретные методы и утверждать, что они работают правильно
- если конкретный метод полагается к unimplemented (абстрактный) метод, вы можете заглушить возвращаемое значение с помощью метода 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-specific.
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, ваш метод должен работать, но это идет вразрез с тенденцией написания теста перед фактическим кодом.
Я бы предложил написать ваши тесты на желаемую функциональность неабстрактного подкласса рассматриваемого абстрактного класса, затем написать как абстрактный класс, так и реализующий подкласс и, наконец, запустить тест.
ваши тесты должны, очевидно, проверить определенные методы абстрактного класса, но всегда через подкласс.
Нельсона-это неправильно.
абстрактные классы не требуют, чтобы все их методы были абстрактными.
реализованные методы, которые нам нужно проверить.
Что вы можете сделать, это создать поддельный класс заглушки в файле модульного теста, расширить абстрактный класс и реализовать только то, что требуется без каких-либо функций вообще, конечно, и проверить это.
Ура.
Если вы не хотите подкласс абстрактного класса только для выполнения модульного теста на методы, которые уже реализованы в абстрактном классе, вы можете попробовать посмотреть, позволяет ли ваша структура mock абстрактные классы.