Как проверить конкретные методы абстрактного класса с помощью PHPUnit?
Я ожидаю, что мне придется создать какой-то объект как часть теста. Тем не менее, я понятия не имею, лучшая практика для этого или если PHPUnit позволяет это.
Как проверить конкретные методы абстрактного класса с помощью PHPUnit?
Я ожидаю, что мне придется создать какой-то объект как часть теста. Тем не менее, я понятия не имею, лучшая практика для этого или если PHPUnit позволяет это.
Ответы:
Модульное тестирование абстрактных классов не обязательно означает тестирование интерфейса, поскольку у абстрактных классов могут быть конкретные методы, и эти конкретные методы могут быть протестированы.
При написании некоторого библиотечного кода не редкость иметь определенный базовый класс, который вы ожидаете расширить на уровне приложения. И если вы хотите убедиться, что код библиотеки протестирован, вам нужны средства для UT конкретных методов абстрактных классов.
Лично я использую 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());
}
}
Макет объекта даст вам несколько вещей:
Это хороший вопрос. Я тоже искал это.
К счастью, в 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
}
Эран, твой метод должен работать, но он идет вразрез с тенденцией написания теста перед реальным кодом.
Я бы предложил написать тесты на желаемую функциональность неабстрактного подкласса рассматриваемого абстрактного класса, затем написать как абстрактный класс, так и реализующий подкласс, и, наконец, запустить тест.
Ваши тесты, очевидно, должны проверять определенные методы абстрактного класса, но всегда через подкласс.
Нельсон ответил неправильно.
Абстрактные классы не требуют, чтобы все их методы были абстрактными.
Реализованные методы - это те, которые нам нужно протестировать.
То, что вы можете сделать, - это создать поддельный класс-заглушку в файле модульного теста, сделать так, чтобы он расширял абстрактный класс и реализовывал только то, что требуется без какой-либо функциональности, конечно, и проверял это.
Приветствия.
Если вы не хотите создавать подкласс абстрактного класса просто для того, чтобы выполнить модульное тестирование методов, которые уже реализованы в абстрактном классе, вы можете попытаться проверить, позволяет ли ваша инфраструктура моделировать абстрактные классы.