Как протестировать класс, использующий Storage Facade?

В пакете Laravel 5, который я делаю, есть класс FileSelector, который использует Storage-facade в определенном методе.

public function filterFilesOnDate($files, DateTime $date)
{
    return array_filter($files, function($file) use($date){
        return Storage::lastModified($file) < $date->getTimeStamp();
    });
}

Этот класс принимает путь (к некоторым файлам) и Storage::disk() в своем конструкторе.

Теперь я пытаюсь написать некоторые базовые модульные тесты для этого конкретного класса, используя Orchestra Testbench.

Функция setUp выглядит так:

protected $fileSelector;
protected $date;

public function setUp()
{
    parent::setUp();
    $this->date = new DateTime();
    $this->fileSelector = new fileSelector('tests/_data/backups', Storage::disk('local'));
}

Неудачный тест:

public function test_if_files_are_filtered_on_date()
{
    $files = Storage::allFiles('tests/_data/backups');

    $filteredFiles = $this->fileSelector->filterFilesOnDate($files, $this->date);
}

Storage::allFiles('tests/_data/backups') возвращает никаких файлов вообще. Путь правильный, так как использование File-facade возвращает необходимые файлы, но это несовместимо с filterFilesOnDate()-методом, так как он использует Storage.

При использовании File-facade возникает следующая ошибка:

League\Flysystem\FileNotFoundException: File not found at tests/_data/backups/ElvisPresley.zip

Я неправильно использую методы хранения в тесте или я наткнулся на ограничение Orchestra/Testbench?


person Matthias    schedule 17.03.2015    source источник


Ответы (1)


Хорошо, оказывается, я не совсем понял, как работают Storageи диски.

Использование таких вещей, как Storage::lastModified(), вызывает файловую систему по умолчанию, указанную в файловой системе-config.

Поскольку это тест, конфигурации нет.

Что делает Storage::disk(), так это создает экземпляр FilesystemAdapter с использованием объекта файловой системы. Поэтому объект хранилища необходимо «воссоздать».

So:

$this->fileSelector = new FileSelector('tests/_data/backups', Storage::disk('local'));

Становится:

$this->disk = new Illuminate\Filesystem\FilesystemAdapter(
    new Filesystem(new Local($this->root))
);

$this->fileSelector = new FileSelector($this->disk, $this->path);

($this->pathэто путь, по которому хранятся файлы, которые я использую для тестирования)

Мне также было указано, что я должен устанавливать временные метки lastModified вручную каждый раз при запуске теста, чтобы избежать различий в результатах теста.

foreach (scandir($this->testFilesPath) as $file)
{
    touch($this->testFilesPath . '/' . $file, time() - (60 * 60 * 24 * 5));
}

Используя touch, вы можете создавать файлы или устанавливать временные метки файлов. В этом случае они устанавливаются на 5 дней.

person Matthias    schedule 19.03.2015