Reputation: 81
In a Laravel 5 package I am making there is a class FileSelector
that uses the Storage-facade in a certain method.
public function filterFilesOnDate($files, DateTime $date)
{
return array_filter($files, function($file) use($date){
return Storage::lastModified($file) < $date->getTimeStamp();
});
}
This class takes a path (to some files) and a Storage::disk()
in it's constructor.
Now I am trying to write some basic unit tests for this specific class using the Orchestra Testbench.
The setUp-function looks like this:
protected $fileSelector;
protected $date;
public function setUp()
{
parent::setUp();
$this->date = new DateTime();
$this->fileSelector = new fileSelector('tests/_data/backups', Storage::disk('local'));
}
The failing test is:
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')
returns no files at all.
The path is correct because using the File-facade returns the needed files but this isn't compatible with the filterFilesOnDate()
-method because it uses Storage.
Using the File-facade generates the following error:
League\Flysystem\FileNotFoundException: File not found at tests/_data/backups/ElvisPresley.zip
Am I using the Storage-methods wrong in the test or have I stumbled on a limitation of Orchestra/Testbench?
Upvotes: 2
Views: 2357
Reputation: 81
Ok, turns out I didn't completely understand how Storage
and disks worked.
Using things like Storage::lastModified()
calls the default Filesystem specified in the filesystem-config.
Since this is a test there is no config.
What Storage::disk()
does, is create an instance of FilesystemAdapter
using a Filesystem-object So a Storage object needs to be 'recreated'.
So:
$this->fileSelector = new FileSelector('tests/_data/backups', Storage::disk('local'));
Becomes:
$this->disk = new Illuminate\Filesystem\FilesystemAdapter(
new Filesystem(new Local($this->root))
);
$this->fileSelector = new FileSelector($this->disk, $this->path);
($this->path
is the path the where the files I use for testing are stored)
It was also pointed out to me that I should set the lastModified-timestamps manually everytime the test is run to avoid differing test results.
foreach (scandir($this->testFilesPath) as $file)
{
touch($this->testFilesPath . '/' . $file, time() - (60 * 60 * 24 * 5));
}
Using touch
you can create files or set timestamps of files. In this case, they are set to 5 days.
Upvotes: 5