Я знаю, что можно проверить частные / защищенные методы с помощью PHPUnit, используя отражение или другие обходные пути.
Но большинство источников говорят мне, что не рекомендуется писать тесты для частных методов внутри класса.
Вы должны тестировать класс так, как если бы это был «черный ящик» – вы просто проверяете ожидаемое поведение, сравнивая входы с выходами без учета внутренней механики. Написание тестов для классов также должно уведомлять вас о неиспользуемых частных методах, демонстрируя отсутствие покрытия кода.
Когда я тестирую свой класс и генерирую отчет в формате HTML, он показывает частные методы, которые не рассматриваются в тестах, хотя строки, из которых они вызваны, полностью выполняются / закрываются. Я знаю, что частные методы выполняются, потому что если бы они не были утверждениями в моем классе, это не было бы.
Является ли это ожидаемым поведением в PHPUnit? Могу ли я стремиться к 100% -ному охвату, но при этом проверяя частные методы только косвенно?
Некоторые упрощенные примеры кода (с использованием RestBundle в Symfony2):
class ApiController extends FOSRestController { /* * @REST\View() * @REST\Get("/api/{codes}") */ public function getCodesAction($codes) { $view = new View(); $view->setHeader('Access-Control-Allow-Origin', '*'); $view->setData(array('type' => 'codes','data' => $this->_stringToArray($codes))); $view->setFormat('json')->setHeader('Content-Type', 'application/json'); return $this->handleView($view); } private function _stringToArray($string){ return explode('+',$string); }
Публичная функция отображается как «закрытая», закрытая функция косвенно покрывается, но в отчетах PHPUnit отображается красным цветом.
Контрольная работа:
class ApiControllerTest extends WebTestCase { public function test_getCodesAction(){ $client = static::createClient(); $client->request('GET', '/api/1+2+3'); $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent()); } }
Разумеется, это просто глупый пример, я мог бы просто включить explode () прямо в публичную функцию; Но контроллеры, с которыми я пишу тесты, содержат гораздо более сложные и повторно используемые частные функции, которые преобразуют данные более сложными способами (но по-прежнему свободны от побочных эффектов).
В Phpunit вы можете указать Covered Methods специальной аннотацией, как описано в документе .
Вы можете сделать что-то вроде этого:
class ApiControllerTest extends WebTestCase { /** * @covers ApiController::getCodesAction * @covers ApiController::_stringToArray */ public function test_getCodesAction(){ $client = static::createClient(); $client->request('GET', '/api/1+2+3'); $this->assertContains('{"type": "codes", "data": [1,2,3]}', $client->getResponse()->getContent()); } }
Надеюсь, что эта помощь