Тест PHPUnit не пройден, поскольку путь к файлу неверен - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь написать простой модульный тест для одной функции в моем приложении Slim PHP.Функция создает каталог с помощью mkdir (), и я хочу, чтобы тест утверждал, что каталог создан успешно.При тестировании с использованием интерфейсного приложения папка создается успешно, однако при запуске теста каталог не найден

1) TestController :: testCreate mkdir (): такого файла или каталога нет

Мы автоматически загружаем классы, используя следующее:

//composer.json
    "autoload": {
        "psr-4": {
            "App\\": "app",
            "tests\\": "tests/"
        }
    }

Это функция, которая создает каталог:

//Controllor.php
public function create($request, $response){
   mkdir("../public/folder");
}

Используя приложение, это создает каталог в следующем месте, какожидается

-app
-public/folder

Это пример тестовой функции:

//TestController.php
public function testCreate(){

    $controller = new Controller($this->container);
    $request = $this->requestFactory();
    $response = new \Slim\Http\Response();

    $response = $controller>create($request, $response, []);
    //Assertions below..
}

Я использую phpunit.xml для начальной загрузки файла autoload.php, вставив bootstrap = "vendor / autoload.php "в конфигурационный файл.

Я также пытался запросить vendor / autoload.php от TestController.php и пытался вручную установить $_SERVER['DOCUMENT_ROOT'] в TestController.php

Как я могу автоматически загружать пространства имен во время работыTestController.php, чтобы функция create () вызывала mkdir () из правильного местоположения?

Ответы [ 2 ]

1 голос
/ 20 июня 2019

У вас есть несколько опций

  1. С vfsStream можно смоделировать файловую систему.Прекрасно работает со всеми функциями PHP, такими как mkdir, file_exists и т. Д. *
  2. Использование Flysystem в качестве библиотеки абстракций для файловой системы.Используйте Null Adapter для тестов.
  3. Создайте пользовательский интерфейс и реализуйте класс реальной файловой системы и макет класса в памяти для тестов.
1 голос
/ 20 июня 2019

Ну, есть небольшая проблема и большая проблема.

Маленький - вы теряете контекст, в частности, рабочий каталог. Таким образом, не ясно, где создается ваш каталог, и действительно ли это место доступно для записи. Чтобы преодолеть это, я бы сделал настраиваемое значение - имя каталога, в котором все должно происходить. Для реального случая использования я бы поставил $ _SERVER ['DOCUMENT_ROOT'] (или любое другое подходящее значение), а для тестов я бы использовал /tmp (или лучше sys_get_temp_dir()).

Чтобы лучше сформулировать первую проблему (о которой вы спрашиваете):

  • в настоящее время ваш код предполагает что-то о работающей среде, и это предположение не является безопасным, как "всегда есть array_keys() функция доступна"
  • это хорошая практика для преобразования таких предположений в настраиваемые значения
  • делая его настраиваемым, также облегчает тестирование, потому что ваша тестовая среда отделена от вашей среды prod / dev / staging

Больший - это не модульный тест, потому что вы проверяете, как ваш код взаимодействует с какой-то внешней сущностью, в данном случае с файловой системой. Это функциональный тест. Чтобы сделать это модульным тестом, вам нужно смоделировать mkdir(), а для этого вам нужно абстрагировать его за некоторый интерфейс, подобный следующему:

interface DirMaker {
    public function mkdir($name);
}

Реализация этого интерфейса также может обрабатывать конфигурацию. И в тесте вы могли бы представить макет, который просто подтверждает тот факт, что mkdir() был вызван, как и ожидалось.

...