Покрытие кода, когда не тестируются защищенные / приватные методы с PHPUnit

Я знаю, что можно тестировать закрытые / защищенные методы с помощью 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 () прямо в публичную функцию; Но контроллеры, для которых я пишу тесты, содержат гораздо более сложные и многократно используемые частные функции, которые преобразуют данные более сложными способами (но по-прежнему не имеют побочных эффектов).

7

Решение

В Phpunit вы можете указать Покрываемые методы со специальной аннотацией, как описано в доктор.

Вы можете сделать что-то вроде этого:

    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());
}

}

Надеюсь это поможет

3

Другие решения

Других решений пока нет …