Во-первых, вы найдете, что этот код значительно проще для модульного тестирования, если бы это не был метод из 200 строк! Чем меньше блок - тем меньше тест. Вы можете извлечь getFileName()
, getContentType()
, isChunked()
или getChunkDetails()
, transferChunk()
и т. Д. Многие из этих методов будут очень короткими и позволят вам тщательно их протестировать, не настраивая всю загрузку. Вот один пример, getContentType()
:
public function getContentType() {
if (isset($_SERVER["CONTENT_TYPE"]))
return $_SERVER["CONTENT_TYPE"];
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
return $_SERVER["HTTP_CONTENT_TYPE"];
throw new FileTransferException('Unknown content type');
}
Тесты для этого метода просты.
/**
* @expectedException FileTransferException
*/
public function testUnknownContentType() {
$fixture = new FileTransfer();
unset($_SERVER["CONTENT_TYPE"]);
unset($_SERVER["HTTP_CONTENT_TYPE"]);
$fixture->getContentType();
}
public function testRegularContentType() {
$fixture = new FileTransfer();
$_SERVER["CONTENT_TYPE"] = 'regular';
unset($_SERVER["HTTP_CONTENT_TYPE"]);
self::assertEquals('regular', $fixture->getContentType());
}
public function testHttpContentType() {
$fixture = new FileTransfer();
unset($_SERVER["CONTENT_TYPE"]);
$_SERVER["HTTP_CONTENT_TYPE"] = 'http';
self::assertEquals('http', $fixture->getContentType());
}
public function testRegularContentTypeTakesPrecedence() {
$fixture = new FileTransfer();
$_SERVER["HTTP_CONTENT_TYPE"] = 'http';
$_SERVER["CONTENT_TYPE"] = 'regular';
self::assertEquals('regular', $fixture->getContentType());
}
Как только вы реорганизуете код с помощью простых вещей, вы можете извлечь всю обработку ввода-вывода в отдельный класс. Таким образом, вы можете использовать фиктивный объект при тестировании кода, не относящегося к вводу-выводу, что означает, что вам не придется полагаться на реальные файлы или заполнять php://input
поддельными данными. Это «модульная» часть «модульного тестирования»: разбивка кода на маленькие тестируемые блоки и удаление других блоков из уравнения, где это практически возможно.
В извлеченном классе обработки ввода / вывода поместите вызовы к is_uploaded_file()
и откройте входной поток для отдельных методов, например, isUploadedFile()
и openInputStream()
. Во время тестирования вы можете издеваться над этими методами, а не над их основными механизмами. Нет смысла тестировать, что is_uploaded_file()
работает в модульном тесте. Это ответственность PHP, и вы можете проверить, что все работает, как ожидается, в интеграционном (сквозном) тесте.
Это сократит тестирование вашего кода ввода-вывода до минимума. На этом этапе вы можете использовать реальные файлы в папке с тестами или в пакете, например vfsStream .